ACM第二次練習—1026

題意:自從2006年3月10日至11日的首屆數獨世界錦標賽以後,數獨這項遊戲越來越受到人們的喜愛和重視。<br>據說,在2008北京奧運會上,會將數獨列爲一個單獨的項目進行比賽,冠軍將有可能獲得的一份巨大的獎品———HDU免費七日遊外加lcy親筆簽名以及同hdu acm team合影留念的機會。<br>所以全球人民前仆後繼,爲了獎品日夜訓練茶飯不思。當然也包括初學者linle,不過他太笨了又沒有多少耐性,只能做做最最基本的數獨題,不過他還是想得到那些獎品,你能幫幫他嗎?你只要把答案告訴他就可以,不用教他是怎麼做的。<br><br>數獨遊戲的規則是這樣的:在一個9x9的方格中,你需要把數字1-9填寫到空格當中,並且使方格的每一行和每一列中都包含1-9這九個數字。同時還要保證,空格中用粗線劃分成9個3x3的方格也同時包含1-9這九個數字。比如有這樣一個題,大家可以仔細觀察一下,在這裏面每行、每列,以及每個3x3的方格都包含1-9這九個數字。

思路:遇到的第一個難題:如何在dfs中找到問號的位置 難道一遍一遍的查找???答案:在主函數中記錄所有問號的位置第二個難題  一行中有多個問號  那怎麼做出這幾個數的全排列 讓其去dfs答案 不用這樣直接在問號處 填寫1-9的數字看是否可行第三個難題如何保證只有一個正確答案答案  自己錯誤理解了題意 對於每組測試數據保證它有且只有一個解 是指只要找到了一個解就不需要再繼續尋找其他解了第4個難題超時了答案如果沒有EOF會 一些小的剪枝和技巧也能解決問題1由於要求先輸入一個數我一開始先輸入1個數  然後在輸入第一行中的數(第一個由於已經輸入所以不包括)   再然後輸入2--9行的數 這樣很複雜也浪費時間代碼中的方法很給力  先輸入一個數 然後在全部遍歷 已經輸入過的 直接continue 不用再輸入     不這樣 會超時2  由於分成多個小方塊   分成了多個9宮格  輸入數據時 如果按數組從1-9輸入沒有明顯的規律不好找出 對於一個x y其位於哪個9宮格 而如果從0-8 輸入  xx = x/3*3; yy = y/3*3;     //則很容易按照這個方法計算屬於哪個9宮格 xxx = xx+3; yyy = yy+3;  3 千千萬萬搞清楚2組解之間有一行空格的含義4這裏的輸入最好用%s  因爲%s 遇到空格或回車就終止了 不會把空格回車符存進去  而用%c  還得在後面加個getchar()雖然這樣也行 但是複雜  況且 這樣能夠造成超時  我試過了這樣能夠造成超時 所以遇到能簡化的地方儘量簡化。

感想:自己做不出來,只好參考別人的。

代碼:

#include<iostream>  
#include<cstdio>  
#include<cstdlib>  
#include<cstring>  
#include<string>  
#include<queue>  
#include<algorithm>  
#include<map>  
#include<iomanip>  
#define INF 99999999  
using namespace std;  
  
const int MAX=10;  
char map_[MAX][MAX];  
int pos[MAX*9][2];//存儲是問號點的座標,方便搜索時只需要搜索這些點填什麼數字.  
bool row[MAX][MAX],list[MAX][MAX];//用來標明哪行哪列出現過什麼數.  
int k;  
  
bool check(int v,int num){  
    int n=pos[v][0]/3*3;//搜索周圍9小格的行的開始搜索位置.  
    int m=pos[v][1]/3*3;//搜索周圍9小格的列的開始搜索位置.  
    for(int i=n;i<n+3;++i){  
        for(int j=m;j<m+3;++j){  
            if(map_[i][j] == num+'0')return false;  
        }  
    }  
    return true;  
}  
  
bool DFS(int v){  
    if(v == k){return true;}//代表前面已經把所有的點都搜索完了.  
    for(int i=1;i<10;++i){  
        if(!row[pos[v][0]][i] && !list[pos[v][1]][i] && check(v,i)){  
            map_[pos[v][0]][pos[v][1]]=i+'0';  
            row[pos[v][0]][i]=true;  
            list[pos[v][1]][i]=true;  
            if(DFS(v+1)){return true;}  
            map_[pos[v][0]][pos[v][1]]='?';  
            row[pos[v][0]][i]=false;  
            list[pos[v][1]][i]=false;  
        }  
    }  
    return false;  
}  
  
void output(){  
    for(int i=0;i<9;++i){  
        cout<<map_[i][0];  
        for(int j=1;j<9;++j){  
            cout<<' '<<map_[i][j];  
        }  
        cout<<endl;  
    }  
    return;  
}  
  
int main(){  
 int num=0;  
    while(1){  
     k=0;  
     memset(row,false,sizeof row);  
     memset(list,false,sizeof list);  
     for(int i=0;i<9;++i){  
          for(int j=0;j<9;++j){  
              if(!(cin>>map_[i][j]))exit(0);  
              if(map_[i][j] == '?'){pos[k][0]=i;pos[k++][1]=j;continue;}  
              row[i][map_[i][j]-'0']=true;  
              list[j][map_[i][j]-'0']=true;  
            }  
        }  
     DFS(0);//開始搜索第1個是問號的點.  
     if(num++)cout<<endl;  
     output();  
    }  
    return 0;  
}   

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章