天天看點

三連擊(NOIP1998)

題目連結:三連擊

典型的打表題,但cgg今天不是教你怎麼打表的,而是教你正解。

這題方法多樣,比如遞歸求解也行,反正資料也不大。

在這裡我提供另一種思路,我們枚舉第一個數,即最小的一個數,然後分解它以及它的兩倍,它的三倍的數位,然後判斷是否又相同的數位,還要注意判斷是否又0的存在(題目是不允許的,但這樣的數卻存在)。下面給出代碼:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int vis[11],num[11];             //1
    for(int i=123;i<=329;i++){       //2
        memset(vis,0,sizeof(vis));   //3
        num[1]=i%10;
        num[2]=i/10%10;
        num[3]=i/10/10%10;
        num[4]=2*i%10;
        num[5]=2*i/10%10;
        num[6]=2*i/10/10%10;
        num[7]=3*i%10;
        num[8]=3*i/10%10;
        num[9]=3*i/10/10%10;
        int ok=1;                    //4
        for(int j=1;j<=9;j++){
            if(vis[num[j]]==0&&num[j]!=0){  //5
                vis[num[j]]=1;
            }else{
                ok=0;
                break;
            }
        }
        if(ok){
            printf("%d %d %d\n",i,2*i,3*i);
        }
    }
    return 0;
}
           

還是提5處,

1處:vis統計數位有沒有用過,num儲存每一個數

2處:由于位數不想重,是以最小為123,又因為i*3<=987,是以i枚舉到329就行

3處:每一輪判斷前要把vis清零

4處:設定辨別符

5處:注意判斷是不是數字0

繼續閱讀