搜尋_DFS_CH2901_靶形數獨
阿新 • • 發佈:2018-11-19
思路分析:
使用DFS, 每次選擇候選填數方案最少的分支遞歸併結合位運算優化即可, 具體如下AC程式碼所示:
//CH2901_靶形數獨 #include <iostream> #include <cstdio> #include <cmath> using namespace std; int G[10][10], fix[10][10];//fix[i][j]非零表示G[i][j]初始給出 int R[10], C[10], A[10];//R[i]第i行可填的數, C[i]第i列可填的數, A[i]第i個9宮格可填的數 int ah[10][10];//ah[i][j]:G[i][j]對應9宮格編號 int res = -1, val, cnt;//cnt:當前已經填好的數個數 int lowbit(int a){ int ans = 0; while(a) a -= a & -a, ++ans; return ans; } void dfs(int x, int y){ if(cnt == 81){ res = max(res, val); return; } for(int i = 1, k = ah[x][y], t = A[k] & R[x] & C[y], s = max(abs(x - 5), abs(y - 5)) ; i <= 9; ++i) if(t >> i - 1 & 1){ G[x][y] = i, R[x] ^= 1 << i - 1, C[y] ^= 1 << i - 1, A[k] ^= 1 << i - 1 , val += i * (10 - s), ++cnt; int nexx, nexy, tmp = 10, f; for(int p = 1; p <= 9; ++p) for(int q = 1; q <= 9; ++q) if(!fix[p][q] && !G[p][q] && (f = lowbit(R[p] & C[q] & A[ah[p][q]])) < tmp) tmp = f, nexx = p, nexy = q; dfs(nexx, nexy); G[x][y] = 0, R[x] ^= 1 << i - 1, C[y] ^= 1 << i - 1, A[k] ^= 1 << i - 1 , val -= i * (10 - s), --cnt; } } int main(){ for(int i = 1; i <= 9; ++i) R[i] = C[i] = A[i] = (1 << 9) - 1; for(int i = 1; i <= 9; ++i) for(int j = 1; j <= 9; ++j){ scanf("%d", &G[i][j]); ah[i][j] = 3 * (i / 3 - !(i % 3) * 1) + j / 3 + 1 - !(j % 3) * 1; if(G[i][j]) fix[i][j] = 1, R[i] ^= 1 << G[i][j] - 1, C[j] ^= 1 << G[i][j] - 1 , A[ah[i][j]] ^= 1 << G[i][j] - 1, ++cnt , val += G[i][j] * (10 - max(abs(i - 5), abs(j - 5))); } int nexx, nexy, tmp = 10, f; for(int p = 1; p <= 9; ++p) for(int q = 1; q <= 9; ++q) if(!fix[p][q] && (f = lowbit(R[p] & C[q] & A[ah[p][q]])) < tmp) tmp = f, nexx = p, nexy = q; dfs(nexx, nexy), cout << res << endl; }