Description
解数独问题
Algorithm
此题用DFS即可
记录每一个?的位置,然后枚举每一个?的数字,用bool OK()来判断
每次DFS后要回溯,即a[x][y] = 0
此题输入格式有要求,所以直接用两个solve来写
Code
#include <cstdio>
#include <iostream>
using namespace std;
struct V
{
int x, y;
};
struct VV
{
int i, x;
};
int a[9][9];
V f[100];
int f_size = 0;
int bs = 0;
bool flag;
bool ok(int x, int y, int z)
{
a[x][y] = z;
bool b[10] = {false};
// 检验x方向
for (int i = 0; i < 9; i++)
if (a[x][i] != 0)
{
if (b[a[x][i]]) return false;
b[a[x][i]] = true;
}
for (int i = 0; i < 10; i++) b[i] = false;
// 检验y方向
for (int i = 0; i < 9; i++)
if (a[i][y] != 0)
{
if (b[a[i][y]]) return false;
b[a[i][y]] = true;
}
// 检验方格
x = x / 3 * 3;
y = y / 3 * 3;
for (int i = 0; i < 10; i++) b[i] = false;
for (int i = x; i < x + 3; i++)
for (int j = y; j < y + 3; j++)
if (a[i][j] != 0)
{
if (b[a[i][j]]) return false;
b[a[i][j]] = true;
}
return true;
}
void print()
{
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
cout << a[i][j];
cout << endl;
}
flag = true;
}
void dfs(const int &k)
{
if (flag) return;
if (k == f_size)
{
print();
return;
}
int x = f[k].x, y = f[k].y;
for (int i = 1; i < 10; i++)
if (ok(x, y, i))
dfs(k + 1);
a[x][y] = 0;
}
void solve0()
{
flag = false;
f_size = 0;
char s[9];
for (int i = 0; i < 9; i++)
{
gets(s);
for (int j = 0; j < 9; j++)
{
if (s[j] != '?') a[i][j] = s[j] - '0'; else a[i][j] = 0;
if (a[i][j] == 0)
{
f[f_size].x = i;
f[f_size].y = j;
f_size++;
}
}
}
dfs(0);
if (!flag) puts("impossible");
}
void solve()
{
flag = false;
f_size = 0;
char s[9];
gets(s);
puts(s);
for (int i = 0; i < 9; i++)
{
gets(s);
for (int j = 0; j < 9; j++)
{
if (s[j] != '?') a[i][j] = s[j] - '0'; else a[i][j] = 0;
if (a[i][j] == 0)
{
f[f_size].x = i;
f[f_size].y = j;
f_size++;
}
}
}
dfs(0);
if (!flag) puts("impossible");
}
int main()
{
int t;
scanf("%d\n", &t);
solve0();
for (int i = 1; i < t; i++)
solve();
}
By the Way
本来是做POJ 2676 的,可惜还是TLE
然后把代码改了一下,过了这题