题意:
第三道数独题目了,还是深搜,这次的空白数量固定5个,开始一直WA,发现了题目中重要的描述,可能给出的puzzle本身就是错的。好吧。
然后就和前两道是一样的了。
代码:
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
char square[10][10];
bool row[10][10], col[10][10], blo[10][10];
int todo, flag, start = 1;
int block(int i, int j) {return (i-1)/3*3 + (j-1)/3 + 1;}
struct TODO
{
int x, y, b, pNum;
TODO() {}
TODO(int _x, int _y): x(_x), y(_y), b(block(_x,_y)), pNum() {}
void calc()
{
for (int i = 1; i <= 9; ++ i)
if (!row[x][i] && !col[y][i] && !blo[b][i])
pNum ++;
}
};
bool cmp(const TODO &a, const TODO &b) {return a.pNum < b.pNum;}
TODO p[85];
void dfs(int n)
{
if (flag || n == todo) { flag = 1; return; }
int xx = p[n].x, yy = p[n].y, bl = p[n].b;
for (int temp = 1; temp <= 9; ++ temp)
{
if (!row[xx][temp] && !col[yy][temp] && !blo[bl][temp])
{
square[xx][yy] = temp+'0';
row[xx][temp] = 1; col[yy][temp] = 1; blo[bl][temp] = 1;
dfs(n+1); if (flag) return;
row[xx][temp] = 0; col[yy][temp] = 0; blo[bl][temp] = 0;
}
}
}
int main()
{
int t;
scanf("%d", &t);
while (t --)
{
if (start) start = 0;
else printf("\n");
flag = 1; todo = 0;
memset(row, false , sizeof(row));
memset(col, false , sizeof(col));
memset(blo, false , sizeof(blo));
for (int i = 1; i <= 9; ++ i)
{
scanf("%s", square[i]+1);
for (int j = 1; j <= 9; ++ j)
{
if (square[i][j] == '0')
p[todo++] = TODO(i,j);
else
{
if (row[i][square[i][j]-'0']) flag = 0;
else row[i][square[i][j]-'0'] = 1;
if (col[j][square[i][j]-'0']) flag = 0;
else col[j][square[i][j]-'0'] = 1;
if (blo[block(i,j)][square[i][j]-'0']) flag = 0;
else blo[block(i,j)][square[i][j]-'0'] = 1;
}
}
}
for (int i = 0; i < todo; ++ i) p[i].calc();
sort(p, p+todo, cmp);
if (flag)
{
flag = 0;
dfs(0);
if (flag)
for (int i = 1; i <= 9; ++ i)
printf("%s\n", square[i]+1);
else
printf("Could not complete this grid.\n");
}
else
printf("Could not complete this grid.\n");
}
}