【qbxt day2(1)】 搜索
使用BFS的必要条件:1.求一个状态到另一个状态的最小步数(但是不考虑代价)
2.状态可压缩,内存可以全部存下
三类搜索问题:1.最优解 2.可行解 3.解的数量
剪枝:三类通用 减掉不可能的情况
最优解特有最优性剪枝
靶形数独:)
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
bool h[10][10],l[10][10],q[10][10];
int num[10][10];
int re=-1;
void dfs(int cnt,bool first);
int go[10][10]={{0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,2,2,2,3,3,3},
{0,1,1,1,2,2,2,3,3,3},
{0,1,1,1,2,2,2,3,3,3},
{0,4,4,4,5,5,5,6,6,6},
{0,4,4,4,5,5,5,6,6,6},
{0,4,4,4,5,5,5,6,6,6},
{0,7,7,7,8,8,8,9,9,9},
{0,7,7,7,8,8,8,9,9,9},
{0,7,7,7,8,8,8,9,9,9},
};
int sc[10][10]={{0,0,0,0,0,0,0,0,0,0},
{0,6,6,6,6,6,6,6,6,6},
{0,6,7,7,7,7,7,7,7,6},
{0,6,7,8,8,8,8,8,7,6},
{0,6,7,8,9,9,9,8,7,6},
{0,6,7,8,9,10,9,8,7,6},
{0,6,7,8,9,9,9,8,7,6},
{0,6,7,8,8,8,8,8,7,6},
{0,6,7,7,7,7,7,7,7,6},
{0,6,6,6,6,6,6,6,6,6}
};
void dfs(int cnt,bool first=true){
int aa=9;
int w,e,r;
if(cnt<81){
for(int i=1;i<=9;i++){
for(int j=1;j<=9;j++){
if(num[i][j]==0){
int minn=0,ga=0,qu=go[i][j];
for(int a=1;a<=9;a++){
if(!l[j][a] && !h[i][a] && !q[qu][a]){
minn++;
ga=a;
}
}
if(minn==1 && first){
l[j][ga]=true;
h[i][ga]=true;
q[qu][ga]=true;
num[i][j]=ga;
dfs(cnt+1,true);
}
if(minn<=aa){
aa=minn;
w=i;
e=j;
r=qu;
}
}
}
}
for(int i=1;i<=9;i++){
if(!h[w][i] && !l[e][i] && !q[r][i]){
h[w][i]=true;
l[e][i]=true;
q[r][i]=true;
num[w][e]=i;
dfs(cnt+1,false);
h[w][i]=false;
l[e][i]=false;
q[r][i]=false;
num[w][e]=0;
}
}
}
else{
int ans=0;
for(int i=1;i<=9;i++){
for(int j=1;j<=9;j++){
ans+=num[i][j]*sc[i][j];
}
}
if(re<ans||re==-1){
re=ans;
}
}
}
int main(){
memset(h,false,sizeof(h));
memset(l,false,sizeof(l));
memset(q,false,sizeof(q));
int cnt=0;
for(int i=1;i<=9;i++){
for(int j=1;j<=9;j++){
cin>>num[i][j];
if(num[i][j]!=0)
{
h[i][num[i][j]]=true;
l[j][num[i][j]]=true;
int qu=go[i][j];
q[qu][num[i][j]]=true;
cnt++;
}
}
}
dfs(cnt,true);
cout<<re;
return 0;
}