code1174 靶形数独
主要是优化搜索顺序
从选择较少的点开始,可以大大提高效率
在search(x,y)找点的时候,对于一个空点(x y),设置一个评分score:
score=min{ 横线x上能填的数字个数,竖线y上...个数,所在大方块中...个数 }
选取score最小的点搜索
代码:
#include<iostream> #include<cstring> #include<cstdlib> using namespace std; const int N = 9; const int Size = N+5; int ans=-1; int data[Size][Size]; bool a[Size][Size],b[Size][Size],c[Size][Size];//行 列 大方格 int numA[Size],numB[Size],numC[Size]; int dx[4]={0,1,0,-1}; int dy[4]={1,0,-1,0}; int dic[Size][Size]={ {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 len[Size]={ 0, 8,6,4,2,1 }; int getscore(){ int ans=0; int x,y; for(int temp=1;temp<=N/2;temp++){ x=y=temp; for(int k=0;k<4;k++){ for(int i=1;i<=len[temp];i++){ ans+=data[x][y]*(temp+5); x+=dx[k];y+=dy[k]; } } } ans+=data[5][5]*10; return ans; } void search(int& x,int& y){ x=y=0; int best=999999,score; for(int i=1;i<=N;i++){ for(int j=1;j<=N;j++){ if(data[i][j]==0){ score=min(numA[i],numB[j]); score=min(score,numC[dic[i][j]]); if(score<best){ x=i;y=j; best=score; } } } } } void dfs(){ int x,y; search(x,y); if(x==0){ ans=max(ans,getscore()); //exit(0); return; } bool num[Size]; memset(num,true,sizeof(num)); int ff=dic[x][y]; for(int k=1;k<=N;k++){ if(a[x][k]==true||b[y][k]==true||c[ff][k]==true) num[k]=false; } for(int k=1;k<=N;k++){ if(num[k]==true){ data[x][y]=k; a[x][k]=true;b[y][k]=true;c[ff][k]=true; numA[x]--;numB[y]--;numC[ff]--; dfs(); numA[x]++;numB[y]++;numC[ff]++; a[x][k]=false;b[y][k]=false;c[ff][k]=false; data[x][y]=0; } } return; } int main(){ freopen("1174.in","r",stdin); for(int i=1;i<=9;i++)numA[i]=numB[i]=numC[i]=9; int x; for(int i=1;i<=N;i++){ for(int j=1;j<=N;j++){ cin>>x; if(x!=0){ a[i][x]=true;numA[i]--; b[j][x]=true;numB[j]--; c[dic[i][j]][x]=true;numC[dic[i][j]]--; } data[i][j]=x; } } dfs(); cout<<ans<<endl; fclose(stdin); return 0; }