Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 10745 | Accepted: 3850 |
Description
In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example,
. | 2 | 7 | 3 | 8 | . | . | 1 | . |
. | 1 | . | . | . | 6 | 7 | 3 | 5 |
. | . | . | . | . | . | . | 2 | 9 |
3 | . | 5 | 6 | 9 | 2 | . | 8 | . |
. | . | . | . | . | . | . | . | . |
. | 6 | . | 1 | 7 | 4 | 5 | . | 3 |
6 | 4 | . | . | . | . | . | . | . |
9 | 5 | 1 | 8 | . | . | . | 7 | . |
. | 8 | . | . | 6 | 5 | 3 | 4 | . |
Given some of the numbers in the grid, your goal is to determine the remaining numbers such that the numbers 1 through 9 appear exactly once in (1) each of nine 3 × 3 subgrids, (2) each of the nine rows, and (3) each of the nine columns.
Input
The input test file will contain multiple cases. Each test case consists of a single line containing 81 characters, which represent the 81 squares of the Sudoku grid, given one row at a time. Each character is either a digit (from 1 to 9) or a period (used to indicate an unfilled square). You may assume that each puzzle in the input will have exactly one solution. The end-of-file is denoted by a single line containing the word “end”.
Output
For each test case, print a line representing the completed Sudoku puzzle.
Sample Input
.2738..1..1...6735.......293.5692.8...........6.1745.364.......9518...7..8..6534.
......52..8.4......3...9...5.1...6..2..7........3.....6...1..........7.4.......3.
end
Sample Output
527389416819426735436751829375692184194538267268174593643217958951843672782965341
416837529982465371735129468571298643293746185864351297647913852359682714128574936
题目大意:
数独求解
分析:
这道题的数据强于POJ2676
所以一般的DFS是TLE的
但本蒟蒻又不会dancing links
所以学习了一种类似于状态压缩的方法来判断每一行,每一列,每一个九宫格的数字使用情况
我们可以对于每一行,每一列,每一个九宫格都用一个9位二进制数来存储,再使用bitset来将可以使用的数字取出
(对于每一个空位优先搜索可用数字少的,可以加快速度)
最后DFS
代码如下
1 #include<stdio.h> 2 #include<algorithm> 3 #include<string.h> 4 using namespace std; 5 int heng[10]; 6 int shu[10]; 7 int ge[10]; 8 int cnt[512],num[512],tot; 9 char ss[10][10]; 10 char s[100]; 11 int ID(int x,int y) 12 { 13 return ((x/3)*3)+(y/3); 14 } 15 void visit(int x,int y,int z) 16 { 17 heng[x]^=1<<z; 18 shu[y]^=1<<z; 19 ge[ID(x,y)]^=1<<z; 20 } 21 bool dfs(int now) 22 { 23 if(now==0)return true; 24 int temp=10,x,y; 25 for(int i=0;i<9;i++) 26 { 27 for(int j=0;j<9;j++) 28 { 29 if(ss[i][j]!='.')continue; 30 int v=heng[i]&shu[j]&ge[ID(i,j)]; 31 if(!v)return false; 32 if(cnt[v]<temp) 33 { 34 temp=cnt[v]; 35 x=i,y=j; 36 } 37 } 38 }//可用数字最少的空位 39 int v=heng[x]&shu[y]&ge[ID(x,y)]; 40 for( ;v ;v-=v&-v) 41 { 42 int z=num[v&-v]; 43 ss[x][y]='1'+z; 44 visit(x,y,z); 45 if(dfs(now-1))return true; 46 visit(x,y,z); 47 ss[x][y]='.'; 48 }//取出数字再DFS 49 return false; 50 } 51 int main() 52 { 53 for(int i=0;i<1<<9;i++) 54 { 55 for(int j=i;j;j-=j&-j)cnt[i]++; 56 } 57 for(int i=0;i<9;i++) 58 { 59 num[1<<i]=i; 60 } 61 while(scanf("%s",s)&&s[0]!='e') 62 { 63 for(int i=0;i<9;i++) 64 { 65 for(int j=0;j<9;j++) 66 { 67 ss[i][j]=s[i*9+j]; 68 } 69 } 70 for(int i=0;i<9;i++) 71 { 72 heng[i]=shu[i]=ge[i]=(1<<9)-1; 73 } 74 tot=0; 75 for(int i=0;i<9;i++) 76 { 77 for(int j=0;j<9;j++) 78 { 79 if(ss[i][j]!='.')visit(i,j,ss[i][j]-'1'); 80 else tot++; 81 } 82 } 83 dfs(tot); 84 for(int i=0;i<9;i++) 85 { 86 for(int j=0;j<9;j++) 87 { 88 s[i*9+j]=ss[i][j]; 89 } 90 } 91 printf("%s ",s); 92 } 93 return 0; 94 }