Luogu1074靶形数独

来源:互联网 发布:算法导论pdf非扫描 编辑:程序博客网 时间:2024/05/17 23:24

Luogu1074靶形数独

一道非常好的启发式搜索题,是noip2009提高组第四题,其实这题的剪枝并不难,用类似八皇后的方法,用heng[]与zong[]还有ge[]三个数组分别

表示行/列/大格中一个数字是否出现过,然后dfs。先每个空格扫过去,找剩下的可能性最小的一格,再对这一格搜索就够了。数独进行到最后可

能性会越来越少,不用担心搜索量过大。

程序头上我悄悄地开了一个O2开关,可以减少大约40ms。

  1 #pragma GCC optimize(2)  2 #include<cstdio>  3 #include<iostream>  4 #include<cstring>  5 using namespace std;  6 const int a[9][9]=  7 {  8 {6,6,6,6,6,6,6,6,6},  9 {6,7,7,7,7,7,7,7,6}, 10 {6,7,8,8,8,8,8,7,6}, 11 {6,7,8,9,9,9,8,7,6}, 12 {6,7,8,9,10,9,8,7,6}, 13 {6,7,8,9,9,9,8,7,6}, 14 {6,7,8,8,8,8,8,7,6}, 15 {6,7,7,7,7,7,7,7,6}, 16 {6,6,6,6,6,6,6,6,6} 17 }; 18 const int n=9; 19 struct node{ 20     bool heng[n][n],zong[n][n],ge[n][n]; 21     int matrix[n][n],filled; 22 }tmp; 23 int value,ans=0; 24 inline int judge(int x,int y) 25 { 26     if(x<=2&&y<=2) return 0; 27     else if(x<=2&&y<=5) return 1; 28     else if(x<=2&&y<=8) return 2; 29     else if(x<=5&&y<=2) return 3; 30     else if(x<=5&&y<=5) return 4; 31     else if(x<=5&&y<=8) return 5; 32     else if(x<=8&&y<=2) return 6; 33     else if(x<=8&&y<=5) return 7; 34     else if(x<=8&&y<=8) return 8; 35 } 36 inline void dfs() 37 { 38     if(tmp.filled==81) 39     { 40         ans=max(ans,value); 41         return; 42     } 43     bool t[10]; 44     int p,q,flag=100,unknown[10],point,size=0; 45     for(int i=0;i<n;i++) 46         for(int j=0;j<n;j++) if(tmp.matrix[i][j]==0) 47         { 48             size=0; 49             for(int k=0;k<n;k++) 50             { 51                 t[k]=(tmp.heng[i][k]||tmp.zong[j][k]||tmp.ge[judge(i,j)][k]); 52                 if(t[k]==0) size++; 53             } 54             if(size==0) return; 55             if(size<flag) 56             { 57                 flag=size; 58                 p=i; 59                 q=j; 60                 point=0; 61                 for(int k=0;k<n;k++) if(t[k]==0) unknown[++point]=k+1; 62             } 63         } 64     tmp.filled++; 65     for(int i=1;i<=point;i++) 66     { 67         tmp.matrix[p][q]=unknown[i]; 68         tmp.heng[p][unknown[i]-1]=1; 69         tmp.zong[q][unknown[i]-1]=1; 70         tmp.ge[judge(p,q)][unknown[i]-1]=1; 71         value+=unknown[i]*a[p][q]; 72         dfs(); 73         value-=unknown[i]*a[p][q]; 74         tmp.heng[p][unknown[i]-1]=0; 75         tmp.zong[q][unknown[i]-1]=0; 76         tmp.ge[judge(p,q)][unknown[i]-1]=0; 77     } 78     tmp.matrix[p][q]=0; 79     tmp.filled--; 80 } 81 int main() 82 { 83     for(int i=0;i<n;i++) 84         for(int j=0;j<n;j++) 85         { 86             scanf("%d",&tmp.matrix[i][j]); 87             if(tmp.matrix[i][j]!=0) 88             { 89                 tmp.heng[i][tmp.matrix[i][j]-1]=1; 90                 tmp.zong[j][tmp.matrix[i][j]-1]=1; 91                 tmp.ge[judge(i,j)][tmp.matrix[i][j]-1]=1; 92                 value+=tmp.matrix[i][j]*a[i][j]; 93                 tmp.filled++; 94             } 95         } 96     dfs(); 97     if(ans==0) printf("-1"); 98     else printf("%d",ans); 99     return 0;100 }

 

0 0
原创粉丝点击