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
- Luogu1074靶形数独
- 【搜索】靶形数独
- 测试靶形数独
- 靶形数独
- 靶形数独
- 靶形数独
- NOIP2009 靶形数独
- NOIP2009 靶形数独
- [codevs1174] 靶形数独
- [vijos1755]靶形数独
- 靶形数独
- NOIP2009 靶形数独
- 靶形数独
- NOIP2009靶形数独
- [P1074]靶形数独
- 靶形数独
- 靶形数独
- noip2009靶形数独
- linux中yum安装mysql5.7
- 还是我 看看1下代码有什么错误
- jQuery-自学笔记(1)——基础入门
- codevs天梯全排列 普通dfs
- 遇到问题----gradle-----myeclipse的gradle插件导入项目报错nsupported major.minor version 51.0
- Luogu1074靶形数独
- The Knowledge of Linux-.-Day06
- linux学习-day05
- VTK修炼之道31:图像二值化_阈值法
- linux学习-day06
- 用户和用户组管理
- 51NOD 1347 旋转字符串
- 待做的题目……
- Jquery实现的几款漂亮的时间轴