题目描述,用程序模拟一下数独。
给你9*9的格子,空格用0表示,输出一种方案,使得每一行,每一列,以及每一宫(3*3)都分别由1-9的数字填入。输出任意方案即可。
解法,此题有各种解法,DFS即可AC。而Discuss说可以用Dancing Links,没用过额。。有空去研究研究。。
我这里用的是DFS+位运算加速判重。700ms水过。。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int mp[10][10],x[10],y[10],e[10],p[3][3];
bool flag;
void DFS(int a,int b)
{
int i,j,t1,t2,t3,ta,tb;
if (b == 10)
{
a++;
b=1;
}
if (a == 10)
{
for (i=1; i<=9; i++)
{
for (j=1; j<=9; j++)
{
printf("%d",mp[i][j]);
}
printf("\n");
}
flag=true;
return ;
}
if (mp[a][b] == 0)
{
ta=(a-1)/3;
tb=(b-1)/3;
for (i=1; i<=9; i++)
{
t1=x[a]&e[i];
t2=y[b]&e[i];
t3=p[ta][tb]&e[i];
if (t1 != 0 || t2 != 0 || t3 != 0)
continue;
mp[a][b]=i;
x[a]|=e[i];
y[b]|=e[i];
p[ta][tb]|=e[i];
DFS(a,b+1);
if (flag == true)
return ;
x[a]-=e[i];
y[b]-=e[i];
p[ta][tb]-=e[i];
mp[a][b]=0;
}
}
else
{
DFS(a,b+1);
}
}
int main()
{
int prob,i,j;
char str[120];
for (i=1; i<=9; i++)
{
e[i]=1<<i;
}
e[0]=0;
scanf("%d",&prob);
getchar();
while (prob--)
{
memset(x,0,sizeof(x));
memset(y,0,sizeof(y));
memset(p,0,sizeof(p));
for (i=1; i<=9; i++)
{
gets(str);
for (j=1; j<=9; j++)
{
mp[i][j]=str[j-1]-'0';
p[(i-1)/3][(j-1)/3]+=e[mp[i][j]];
x[i]+=e[mp[i][j]];
y[j]+=e[mp[i][j]];
}
}
flag=false;
DFS(1,1);
}
}