题意:
数独问题,给出一些点,然后要求填满格子。每行没列1-9不能重复,每个3*3的小格子也不能重复。
分析:
暴力搜索,那么主要的问题就是每次如何判断是否冲突。行和列的比较好想,row[i][j]=1表示第i行的j已经被占了,col[i][j]=1表示第i列的j已经被占了,那么每个小格子呢?
首先,每行每列都是012、345、678那么每个j/3表示它在这以行的第j/3个格子里,i/3表示在第i/3行的格子,那么i/3*3+j/3就表示该点处于那个小格子里,同理g[i][j]表示第i个格子里的j已经被占了。
ok,剩下的就是代码递归实现了。
另外poj2918和本题是一样的,只不过输入输出格式不一样。亲测代码改过能AC。另外,poj的数独问题还有poj3074,poj3076 ,难度分别是poj2076=poj2918
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <algorithm>
#define read freopen("q.in","r",stdin)
#define LL long long
#define maxn 1000
using namespace std;
char mp[10][10];
int grid[10][10];
bool row[10][10],col[10][10];
bool g[10][10];
bool dfs(int d)
{
// cout<<d<<endl;
if(d==81)return true;
int x=d/9+1,y=d%9+1;
bool f=false;
if(grid[x][y])
return dfs(d+1);
else
{
int t=((x-1)/3)*3+(y-1)/3+1;
for(int i=1;i<=9;i++)
{
//cout<<"EEE"<<f<<endl;
if( !col[y][i] && !row[x][i] && !g[t][i])
{
grid[x][y]=i;
col[y][i]=true;row[x][i]=true;g[t][i]=true;
f= dfs(d+1);
if(f)return true;
else{
col[y][i]=false;row[x][i]=false;g[t][i]=false;grid[x][y]=0;
}
}
}
}
return false;
}
int main()
{
// read;
int t;
scanf("%d",&t);
while(t--)
{
int i,j;
memset(row,false,sizeof(row));
memset(col,false,sizeof(col));
memset(grid,0,sizeof(grid));
memset(g,false,sizeof(g));
for(i=1;i<=9;i++)
{
for(j=1;j<=9;j++)
{
cin>>mp[i][j];
grid[i][j]=mp[i][j]-‘0‘;
if(grid[i][j])
{
int tmp=grid[i][j];
row[i][tmp]=true;
col[j][tmp]=true;
int x=((i-1)/3)*3+(j-1)/3+1;
g[x][tmp]=true;
}
}
}
bool flag= dfs(0);
// cout<<flag<<endl;
for(i=1;i<=9;i++)
{
for(j=1;j<=9;j++)cout<<grid[i][j];
cout<<endl;
}
}
}
原文地址:http://blog.csdn.net/u010582475/article/details/45851933