POJ2676 Sudoku

来源:互联网 发布:python enumerate 编辑:程序博客网 时间:2024/05/22 02:20

第一篇博客送给数独吧~

题目大意就是填数独(如同废话)

没有进行搜索顺序剪枝,532ms过的...

分析:

用二进制来存储可以填的数,用a[i]表示i行可以填的数,b[i]表示i列可以填的数,c[i][j]表示第i行j列的九宫格可以填的数。

当准备填一个数的时候,把它所在的行、列、九宫格做“与”运算,用lowbit()得到它能填的所有数。

接下来就是每次递归失败后把a, b, c和num数组复原,用到了memcpy函数(不用memcpy就是多写3行而已)

还有就是我的二进制操作很多没加括号,建议大家不要学我...

最后就是多组数据记得清空。

#include <iostream>#include <cstdio>#include <cstring>using namespace std;int T, num[9][9], a[9], b[9], c[3][3], m[257];char s;bool dfs(int x, int y) {if(x == 9) {for(int i = 0; i < 9; i++, printf("\n"))for(int j = 0; j < 9; j++)printf("%d", num[i][j]);return true;}if(num[x][y]) return dfs(y==8?x+1:x, y==8?0:y+1);int ss = a[x] & b[y] & c[x/3][y/3], aa[9], bb[9], cc[3][3], t;memcpy(aa, a, sizeof a);memcpy(bb, b, sizeof b);memcpy(cc, c, sizeof c);while(t = m[ss & -ss]) {num[x][y] = t;if(a[x] & 1<<t-1)a[x] ^= 1<<t-1;if(b[y] & 1<<t-1)b[y] ^= 1<<t-1;if(c[x/3][y/3] & 1<<t-1)c[x/3][y/3] ^= 1<<t-1;if(dfs(y==8?x+1:x, y==8?0:y+1)) return true;num[x][y] = 0;memcpy(a, aa, sizeof a);memcpy(b, bb, sizeof b);memcpy(c, cc, sizeof c);ss ^= ss & -ss;}return false;}int main() {for(int i = 1; i <= 9; i++)m[1<<i-1] = i;scanf("%d", &T);while(T--) {for(int i = 0; i < 9; i++)a[i] = b[i] = (1<<9)-1;for(int i = 0; i < 3; i++)for(int j = 0; j < 3; j++)c[i][j] = (1<<9)-1;for(int i = 0; i < 9; i++)for(int j = 0; j < 9; j++) {cin>>s;int t = s-'0';num[i][j] = t;if(t) {if(a[i] & 1<<t-1)a[i] ^= 1<<t-1;if(b[j] & 1<<t-1)b[j] ^= 1<<t-1;if(c[i/3][j/3] & 1<<t-1)c[i/3][j/3] ^= 1<<t-1;}}dfs(0, 0);}return 0;}


3 0