題意:自從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;
}