思路
题意就是让完成数独游戏。
从第一个格子开始,依次尝试各种可能。当前节点填入的数字,不能与当前行,当前列,当前九宫格中现存的数字重复。
这是最基本的思路,很容易超时,不过这道题的数据比较特别。倒着搜,也就是从最后一个节点开始尝试,会非常快,代码稍微改一下就行。
下面这个是从前面搜的,还有一道几乎一样的题,POJ - 2918
代码
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int shudo[12][12];
void input()
{
for(int i=1; i<=9; i++)
for(int j=1; j<=9; j++)
scanf("%1d", shudo[i]+j);
}
void output()
{
for(int i=1; i<=9; i++)
{
for(int j=1; j<=9; j++)
printf("%d", shudo[i][j]);
printf("\n");
}
}
bool judge(int x, int y, int num)
{
// 当前行列
for(int i=1; i<=9; i++)
if(num==shudo[x][i]) return false;
for(int i=1; i<=9; i++)
if(num==shudo[i][y]) return false;
// 当前方格
int px = x - ((x%3)?(x%3):3);
int py = y - ((y%3)?(y%3):3);
for(int i=1; i<=3; i++)
for(int j=1; j<=3; j++)
if(num==shudo[px+i][py+j]) return false;
return true;
}
void solve(int x, int y, bool& flag)
{
if(y>9) y -= 9, x++;
if(x>9)
{
flag = true;
return;
}
if(!shudo[x][y])
{
for(int i=1; i<=9; i++)
{
if(judge(x, y, i))
{
shudo[x][y] = i;
solve(x, y+1, flag);
}
if(flag) return;
}
shudo[x][y] = 0;
}
else solve(x, y+1, flag);
}
int main()
{
int t;
bool flag;
scanf("%d", &t);
while(t--)
{
input();
solve(1, 1, flag=false);
output();
}
return 0;
}