Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 530 Accepted Submission(s): 146
In this problem, let us focus on puzzles with 16×16 grids, which consist of 4×4 regions. The objective is to fill the whole grid with hexadecimal digits, i.e. 0123456789ABCDEF, so that each column, each row, and each region contains all hexadecimal digits. The figure below shows a solved sudoku.
Yesterday, Kazari solved a sudoku and left it on the desk. However, Minato played a joke with her - he performed the following operation several times.
* Choose a region and rotate it by 90 degrees counterclockwise.
She burst into tears as soon as she found the sudoku was broken because of rotations.
Could you let her know how many operations her brother performed at least?
Each test case consists of exactly 16 lines with 16 characters each, describing a broken sudoku.
当时总感觉复杂度会炸,后来看题解才悟到其实由于数独的限制性较强,可以减去很大一部分无用解,然后就是普通的深搜了,
关键在于如何处理这个棋盘,我是一个一个区域处理的,枚举每个区域的旋转次数,如果和之前的不冲突就往下一个区域dfs,注意的是
函数返回的时候要将rotate过得区域再ratate回去。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define inf 0x3f3f3f3f 4 int ans,h[20],c[20],e[20][20],g[20][20]; 5 bool vis[20]; 6 void rotate(int a,int b){ 7 int i1,i2,j1,j2; 8 for(i1=4*a-3,j2=4*b-3;i1<=4*a;++i1,j2++){ 9 for(j1=4*b-3,i2=4*a;j1<=4*b;++j1,i2--){ 10 g[i1][j1]=e[i2][j2]; 11 } 12 } 13 for(int i=4*a-3;i<=4*a;++i){ 14 for(int j=4*b-3;j<=4*b;++j){ 15 e[i][j]=g[i][j]; 16 } 17 } 18 } 19 bool ok(int x,int y){ 20 for(int i=4*x-3;i<=4*x;++i){ 21 memset(vis,0,sizeof(vis)); 22 for(int j=1;j<=y*4;++j){ 23 if(vis[e[i][j]]) return 0; 24 vis[e[i][j]]=1; 25 } 26 } 27 for(int j=4*y-3;j<=4*y;++j){ 28 memset(vis,0,sizeof(vis)); 29 for(int i=1;i<=4*x;++i){ 30 if(vis[e[i][j]]) return 0; 31 vis[e[i][j]]=1; 32 } 33 } 34 return 1; 35 } 36 void dfs(int x,int y,int tmp){ 37 if(x>4){ 38 if(tmp<ans) ans=tmp; 39 return; 40 } 41 if(tmp>=ans) return; 42 for(int i=0;i<4;++i){ 43 if(i) rotate(x,y); 44 if(ok(x,y)){ 45 if(y==4) dfs(x+1,1,tmp+i); 46 else dfs(x,y+1,tmp+i); 47 } 48 } 49 rotate(x,y);//再转一次相当于归回原位 50 } 51 int main(){ 52 int t,n,m,i,j,k; 53 char ch; 54 cin>>t; 55 while(t--){ 56 for(i=1;i<=16;++i){ 57 for(j=1;j<=16;++j){ 58 cin>>ch; 59 e[i][j]=isdigit(ch)?ch-'0':ch-'A'+10; 60 } 61 } 62 ans=inf; 63 dfs(1,1,0); 64 cout<<ans<<endl; 65 } 66 return 0; 67 }