1. 程式人生 > >HDU 1426 Sudoku Killer(dfs 解數獨)

HDU 1426 Sudoku Killer(dfs 解數獨)

java oid recommend 還要 targe 個數 else content 字符數

傳送門:

http://acm.hdu.edu.cn/showproblem.php?pid=1426

Sudoku Killer

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 9804 Accepted Submission(s): 2944


Problem Description 自從2006年3月10日至11日的首屆數獨世界錦標賽以後,數獨這項遊戲越來越受到人們的喜愛和重視。
據說,在2008北京奧運會上,會將數獨列為一個單獨的項目進行比賽,冠軍將有可能獲得的一份巨大的獎品———HDU免費七日遊外加lcy親筆簽名以及同hdu acm team合影留念的機會。
所以全球人民前仆後繼,為了獎品日夜訓練茶飯不思。當然也包括初學者linle,不過他太笨了又沒有多少耐性,只能做做最最基本的數獨題,不過他還是想得到那些獎品,你能幫幫他嗎?你只要把答案告訴他就可以,不用教他是怎麽做的。

數獨遊戲的規則是這樣的:在一個9x9的方格中,你需要把數字1-9填寫到空格當中,並且使方格的每一行和每一列中都包含1-9這九個數字。同時還要保證,空格中用粗線劃分成9個3x3的方格也同時包含1-9這九個數字。比如有這樣一個題,大家可以仔細觀察一下,在這裏面每行、每列,以及每個3x3的方格都包含1-9這九個數字。

例題:
技術分享圖片


答案:
技術分享圖片

Input 本題包含多組測試,每組之間由一個空行隔開。每組測試會給你一個 9*9 的矩陣,同一行相鄰的兩個元素用一個空格分開。其中1-9代表該位置的已經填好的數,問號(?)表示需要你填的數。

Output 對於每組測試,請輸出它的解,同一行相鄰的兩個數用一個空格分開。兩組解之間要一個空行。
對於每組測試數據保證它有且只有一個解。

Sample Input 7 1 2 ? 6 ? 3 5 8 ? 6 5 2 ? 7 1 ? 4 ? ? 8 5 1 3 6 7 2 9 2 4 ? 5 6 ? 3 7 5 ? 6 ? ? ? 2 4 1 1 ? 3 7 2 ? 9 ? 5 ? ? 1 9 7 5 4 8 6 6 ? 7 8 3 ? 5 1 9 8 5 9 ? 4 ? ? 2 3

Sample Output 7 1 2 4 6 9 3 5 8 3 6 5 2 8 7 1 9 4 4 9 8 5 1 3 6 7 2 9 2 4 1 5 6 8 3 7 5 7 6 3 9 8 2 4 1 1 8 3 7 2 4 9 6 5 2 3 1 9 7 5 4 8 6 6 4 7 8 3 2 5 1 9 8 5 9 6 4 1 7 2 3

Author linle

Source ACM暑期集訓隊練習賽(三)

Recommend LL | We have carefully selected several similar problems for you: 1045 2614 1067 1455 2952 分析: 唉,沒有心情分析了,先貼一下代碼,找時間回來分析 code:
#include<iostream>
#include
<algorithm> #include<stdio.h> #include<queue> #include<set> #include<map> #include<string> #include<memory.h> using namespace std; void putresult(int b[9][9])//輸出結果 { for(int i=0; i<9; i++) { for(int j=0; j<9; j++) { if(j!=8) cout<<b[i][j]<< ; else cout<<b[i][j]; } cout<<endl; } } void char2int(char a[9][20],int b[9][9])//字符數組轉整型數組 { for(int i=0; i<9; i++) { for(int j=0; j<18; j++) { if(a[i][j]==?) { b[i][j/2]=0; } else if(a[i][j]>=1&&a[i][j]<=9) { b[i][j/2]=a[i][j]-0; } } } } bool judge(int curx,int cury,int num,const int b[9][9]) { int i,j; for(i=0; i<9; i++) // if(i!=cury && b[curx][i]==num) return true; for(i=0; i<9; i++) // if(i!=curx && b[i][cury]==num) return true; int x,y; x = curx/3*3; y = cury/3*3; for(i=0; i<3; i++) //小九宮格 for(j=0; j<3; j++) if(x+i!=curx && y+j!=cury && b[x+i][y+j]==num) return true; return false; } bool dfs(int b[9][9]) { //找到當前第一個‘?‘位置。如果沒有找到,表示所有位置都已填上,即為正確結果,遞歸結束 int i,j; for(i=0; i<9; i++) for(j=0; j<9; j++) if(b[i][j]==0) //找‘?‘的位置 goto label; label: if(i>=9 && j>=9) //找到正確結果了,遞歸結束 return true; //記錄坐標 int curx = i,cury = j; //確定該位置的可以填的數字 bool temp[10]; //記錄哪些數字可以填 int num=0; //記錄當前位置可以填的數字的個數 for(i=1; i<=9; i++) if(judge(curx,cury,i,b)) //判斷這個位置可不可以放這個數字 temp[i] = false; else { temp[i] = true; num++; } if(num==0) return false; //確定下一個位置 for(i=1; i<=9; i++) if(temp[i]) { //這個數在這個位置可以填 if(judge(curx,cury,i,b)) continue; b[curx][cury] = i; if(dfs(b)) return true; } b[curx][cury] = 0; //回退 return false; } int main() { char a[9][20]; int b[9][9]; int i; for(i=0; i<9; i++) { cin.getline(a[i],20,\n); } char2int(a,b); if(dfs(b)) { putresult(b); } while(cin.getline(a[0],20,\n)) { cout<<endl; char a[9][20]; int b[9][9]; int i; for(i=0; i<9; i++) { cin.getline(a[i],20,\n); } char2int(a,b); if(dfs(b)) { putresult(b); } } return 0; }

HDU 1426 Sudoku Killer(dfs 解數獨)