题意:
给你16个16宫格的数独,里面是0~F,你可以逆时针旋转里面的每个16宫格
问你它是从标准数独逆时针旋转多少次得到?
思路:
可以知道每个16宫已经是标准的了,接下来只要考虑每行、每列就行了
那么我们在dfs中就可以用两个行列两个数组来标记每个数字出现的次数,
大于1则不行
另外此时是逆时针来的,那么你就要顺时针回去
逆一次等于顺3次
参考博客:https://www.cnblogs.com/zquzjx/p/10326048.html
代码:
#include<bits/stdc++.h> using namespace std; #define INF 0x3f3f3f3f #define N 25 int g[N][N],G[N][N]; int R[N][N],C[N][N]; int ans; int get(int x,int y,int I,int J,int k) { if(k==1) return g[y+4-J+1][x+I]; else if(k==2) return g[x+4-I+1][y+4-J+1]; else if(k==3) return g[x][y+4-I+1]; else return g[x+I][y+J]; } bool Rotate(int x,int y,int k) { bool flag=1; for(int i=1;i<5;i++) { for(int j=1;j<5;j++) { int xx=(x-1)*4+i; int yy=(y-1)*4+j; G[xx][yy]=get(xx,yy,i,j,k);//cout<<xx<<" "<<yy<<" "<<G[xx][yy]<<endl; // cout<<(x-1)*4+i<<" "<<(y-1)*4+j<<endl; int r=++R[xx][G[xx][yy]]; int l=++C[yy][G[xx][yy]]; if(r>1||l>1) flag=0; } } return flag; } void reRotate(int x,int y) { for(int i=1;i<5;i++) { for(int j=1;j<5;j++) { int xx=(x-1)*4+i; int yy=(y-1)*4+j; --R[xx][G[xx][yy]]; --C[yy][G[xx][yy]]; G[xx][yy]=g[xx][yy]; } } } void dfs(int x,int y,int sum) { if(x==5) { ans=min(ans,sum); return ; } for(int i=0;i<=3;i++) { if(!Rotate(x,y,i)) { reRotate(x,y); continue; } if(y==4) dfs(x+1,1,sum+i); else dfs(x,y+1,sum+i); reRotate(x,y); } } int main() { int T; scanf("%d",&T); while(T--) { char s[25]; for(int i=1;i<=16;i++) { scanf("%s",s+1); for(int j=1;j<=16;j++) { if(s[j]>='0'&&s[j]<='9') g[i][j]=s[j]-'0'+1; else g[i][j]=s[j]-'A'+11; } } /*for(int i=1;i<=16;i++){ for(int j=1;j<=16;j++) printf("%d",g[i][j]); cout<<endl;}*/ memset(R,0,sizeof(R)); memset(C,0,sizeof(C)); ans=INF; dfs(1,1,0); printf("%d\n",ans); } return 0; }