第一篇博客送给数独吧~
题目大意就是填数独(如同废话)
没有进行搜索顺序剪枝,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; }