题目链接
http://poj.org/problem?id=2676
解题思路
思路是很简单的,类似于八皇后问题;
暴力搜: 用h[i][j]标记第i行中是否存在j;同理,l[i][j]标识第i列中是否存在j;k[i][j]第i个方块中是否存在j;
难的是如何进行剪枝,可行的一个方法是记录每个初始为0的点的坐标与可能放置的数字的个数,从少往多遍历,这样能有效的减小搜索树的规模。
总结
(剪枝优化待更新~~)
代码展示
#include<bits/stdc++.h>
using namespace std;
/*
*/
int G[10][10];
bool h[10][10];//第i行是否含有j
bool l[10][10];//第i列是否含有j
bool k[10][10];//第k个九宫格~
bool flag;
void DFS(int x,int y){
if(flag)return;
if(y>9){
x+=1;
y=1;
}
if(x>=10){
for(int i=1;i<=9;i++){
for(int j=1;j<=9;j++)
cout<<G[i][j];
}
cout<<endl;
flag=true;
return;
}
if(G[x][y]){
DFS(x,y+1);
}
else {
for(int num=1;num<=9;num++){
if(h[x][num]||l[y][num])continue;
int m=((x-1)/3 )* 3+(y-1)/3+1;
if(k[m][num])continue;
h[x][num]=1;l[y][num]=1;k[m][num]=1;
G[x][y]=num;
DFS(x,y+1);
h[x][num]=0;l[y][num]=0;k[m][num]=0;
G[x][y]=0;
}
}
}
int main(){
bool Judge=true;
while(true){
memset(G,0,sizeof(G));
memset(h,0,sizeof(h));
memset(l,0,sizeof(l));
memset(k,0,sizeof(k));
flag=false;
for(int i=1;i<=9;i++){
for(int j=1;j<=9;j++){
char c;
cin>>c;
if(c=='e'){
Judge=false;
// cout<<i<<" "<<j<<endl;
break;
}
int f=0;
if(isdigit(c))f=c-'0';
G[i][j]=f;
if(G[i][j]!=0){
h[i][f]=1;l[j][f]=1;
int tk=((i-1)/3 )* 3+(j-1)/3+1;
k[tk][f]=1;
}
}
if(!Judge)break;
}if(!Judge)break;
DFS(1,1);
}
return 0;
}