标签:优化 映射 状态 square test 顺序 else val character
In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example,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.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”.
bool dfs(int now) {
if (now == 0) return 1;
int temp = 10, x, y;
for (int i = 0; i < 9; i++)//确定搜索顺序,找寻可以填数字量最少的位置
for (int j = 0; j < 9; j++) {
if (str[i][j] != '.') continue;
int val = row[i] & col[j] & grid[g(i, j)];
if (!val) return 0;
if (cnt[val] < temp) {
temp = cnt[val];
x = i, y = j;
}
}
int val = row[x] & col[y] & grid[g(x, y)];//确定该位置可以填的数字
for (; val; val -= val&-val) {
int z = num[val&-val];//num是一个二进制和该数字的映射
str[x][y] = '1' + z;
flip(x, y, z);
if (dfs(now - 1)) return 1;//遍历,利用return提前终止
flip(x, y, z);
str[x][y] = '.';
}
return 0;
}
inline int g(int x, int y) {
return ((x / 3) * 3) + (y / 3);//确定格子
}
inline void flip(int x, int y, int z) {
//反转
row[x] ^= 1 << z;
col[y] ^= 1 << z;
grid[g(x, y)] ^= 1 << z;
}
for (int i = 0; i < 1 << 9; i++)
for (int j = i; j; j -= j&-j) cnt[i]++;
for (int i = 0; i < 9; i++)
num[1 << i] = i;
for (int i = 0; i < 9; i++) row[i] = col[i] = grid[i] = (1 << 9) - 1;
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
if (str[i][j] != '.') flip(i, j, str[i][j] - '1');
else tot++;
dfs(tot);
标签:优化 映射 状态 square test 顺序 else val character
原文地址:https://www.cnblogs.com/rign/p/10134306.html