题目描述:都玩过这个游戏,同行同列不能出现相同的数字,同一个9格子中也不能相同的出现。
解决:dfs+回溯
把每行每列不能用的元素检出来,在搜索的时候看每9个格子的情况,用check函数, 用两个vis数组存放行的信息和列的信息
#include <iostream>
#include <cstdio>
using namespace std;
int map[10][10];
bool vis1[10][10],vis2[10][10];
bool found;
bool check(int x,int y,int val)
{//检测每9个格子中的数是否重复
for(int i=(x-1)/3*3+1;i<=(x-1)/3*3+3;i++)
for(int j=(y-1)/3*3+1;j<=(y-1)/3*3+3;j++)
if(map[i][j]==val)return false;
return true;
}
void show()
{
for(int i=1;i<=9;i++)
{
for(int j=1;j<=9;j++)printf("%d",map[i][j]);
printf("\n");
}
}
void dfs(int x,int y)
{
if(found)return;
//返回条件是x=9并且y=10
if(x==9 && y==10){found=true; show();return; }
//若y=10,进行下一行
if(y==10)dfs(x+1,1);
//下标为x,y的元素是否已经有了数字,有数字的话进行下一个,
//没有的话填写数,并回溯
if(map[x][y])dfs(x,y+1);
else
{
for(int i=1;i<=9;i++)
{
if(!vis1[x][i] && !vis2[y][i] && check(x,y,i) )
{
if(y<=9)
{
vis1[x][i]=1;
vis2[y][i]=1;
map[x][y]=i;
dfs(x,y+1);
vis1[x][i]=0;
vis2[y][i]=0;
map[x][y]=0;
}
}
}
}
}
int main()
{
int icase;
scanf("%d",&icase);
while(icase--)
{
char c;
found=false;
memset(vis1,0,sizeof(vis1));
memset(vis2,0,sizeof(vis2));
//预处理
for(int i=1;i<=9;i++)
{
getchar();
for(int j=1;j<=9;j++)
{
scanf("%c",&c);
map[i][j]=c-'0';
if(map[i][j])
{//vis1数组存放的是行中是否使用,vis2存放列中某个数是否使用
vis1[i][map[i][j]]=1;
vis2[j][map[i][j]]=1;
}
}
}
//下标从1开始
dfs(1,1);
}
system("pause");
return 0;
}
浙公网安备 33010602011771号