| Time Limit: 2000MS | Memory Limit: 65536K | |||
| Total Submissions: 16161 | Accepted: 7894 | Special Judge | ||
Description

Input
Output
Sample Input
1 103000509 002109400 000704000 300502006 060000050 700803004 000401000 009205800 804000107
Sample Output
143628579 572139468 986754231 391542786 468917352 725863914 237481695 619275843 854396127
数独游戏,0代表空格,让你填入数字,使得每行每列都是1-9。
通过i,j,与网格关系可得出关系式:k = 3 * ((i - 1) / 3) + (j - 1) / 3 + 1,用来标记网格vis。每组数据从(1, 1)开始dfs,dfs内首先判断当前数字是0还是非0,若为非0则判断是否已经到了第九列,是的话就dfs下一行,否则dfs下一列(也就是遍历所有)。若当前数字为0则从1到9扫一遍,若扫到当前行当前列且网格的第i个未访问,就标记,而后再判断是否是第9列,最后判断是否符合题意,不符合则当前网格修改回去。
AC代码:
#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
using namespace std;
const int MAXN = 10;
int map[MAXN][MAXN];
bool row[MAXN][MAXN], col[MAXN][MAXN], vis[MAXN][MAXN];
bool dfs(int x, int y)
{
if(x == 10) return true;
bool flag = false;
if(map[x][y]) {
if(y == 9) flag = dfs(x + 1, 1);
else flag = dfs(x, y + 1);
if(flag) return true;
else return false;
}
else {
int k = 3 * ((x - 1) / 3) + (y - 1) / 3 + 1;
for(int i = 1; i <= 9; ++i)
if(!row[x][i] && !col[y][i] && !vis[k][i]) {
map[x][y] = i;
row[x][i] = true;
col[y][i] = true;
vis[k][i] = true;
if(y == 9) flag = dfs(x + 1, 1);
else flag = dfs(x, y + 1);
if(!flag) {
map[x][y] = 0;
row[x][i] = false;
col[y][i] = false;
vis[k][i] = false;
}
else return true;
}
}
return false;
}
int main(int argc, char const *argv[])
{
int t;
cin >> t;
while(t--) {
memset(row, false, sizeof(row));
memset(col, false, sizeof(col));
memset(vis, false, sizeof(vis));
char s[MAXN][MAXN];
for(int i = 1; i <= 9; ++i)
for(int j = 1; j <= 9; ++j) {
cin >> s[i][j];
map[i][j] = s[i][j] - '0';
if(map[i][j]) {
int k = 3 * ((i - 1) / 3) + (j - 1) / 3 + 1;
row[i][map[i][j]] = true;
col[j][map[i][j]] = true;
vis[k][map[i][j]] = true;
}
}
dfs(1, 1);
for(int i = 1; i <= 9; ++i) {
for(int j = 1; j <= 9; ++j)
cout << map[i][j];
cout << endl;
}
}
return 0;
}
1005



被折叠的 条评论
为什么被折叠?



