HDU6341
题解:参考了大佬的代码。其实还是比较好理解。
- 矩阵的旋转操作,自己摸索,还是比较好想。
- 剪枝:每次搜索到一个块,判断和前面的块是否冲突。
代码:
#include <bits/stdc++.h>
using namespace std;
int const N = 20;
char c;
int mp[N][N],ans;
bool vis[N];
void rotate(int x,int y){
int tmp[22][22] = {0};
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++)
tmp[j][4-i+1] = mp[4*(x-1)+i][4*(y-1)+j];
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++)
mp[4*(x-1)+i][4*(y-1)+j] = tmp[i][j];
}
bool check(int x,int y){
for(int i=4*x-3;i<=4*x;i++){
memset(vis,0,sizeof(vis));
for(int j=1;j<=4*y;j++){
if(!vis[mp[i][j]]) vis[mp[i][j]] = true;
else return false;
}
}
for(int i=4*y-3;i<=4*y;i++){
memset(vis,0,sizeof(vis));
for(int j=1;j<=4*x;j++){
if(!vis[mp[j][i]]) vis[mp[j][i]] = true;
else return false;
}
}
return true;
}
void dfs(int x,int y,int sum){
if(sum >= ans) return;
if(x == 5){
ans = sum;
return;
}
int nx = x,ny = y+1;
if(ny == 5) nx++,ny = 1;
for(int i=0;i<4;i++){
if(check(x,y))
dfs(nx,ny,sum+i);rotate(x,y);
}
}
int main(){
int T;
scanf("%d",&T);
while(T--){
char s[N];
for(int i=1;i<=16;i++){
scanf(" %s",s+1);
for(int j=1;j<=16;j++){
if(s[j] <='9')
mp[i][j] = s[j] - '0';
else mp[i][j] = s[j] - 'A' + 10;
}
}
ans = 55;
dfs(1,1,0);
printf("%d\n",ans);
}
return 0;
}