http://acm.hdu.edu.cn/showproblem.php?pid=6341
思路:直接dfs,搜索每个格子是否符合,不符合就旋转,找到最小的
代码:
#include<bits/stdc++.h>
using namespace std;
char c[25][25];
int a[25][25];
int vis[25];
int ans,flag;
void rot(int x,int y)
{
int b[4][4];
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
b[j][3-i]=a[i+x][j+y];
}
}
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
a[i+x][j+y]=b[i][j];
}
}
}
bool check(int x,int y)
{
for(int i=x;i<x+4;i++)
{
flag++;
for(int j=0;j<y+4;j++)
{
if(vis[a[i][j]]==flag)
return 0;
vis[a[i][j]]=flag;
}
}
for(int j=y;j<y+4;j++)
{
flag++;
for(int i=0;i<x+4;i++)
{
if(vis[a[i][j]]==flag)
return 0;
vis[a[i][j]]=flag;
}
}
return 1;
}
void dfs(int x,int y,int sum)
{
if(sum>=ans)
return;
if(x==4)
{
ans=min(ans,sum);
return;
}
if(y==4)
dfs(x+1,0,sum);
for(int i=0;i<4;i++)
{
if(check(4*x,4*y))
dfs(x,y+1,sum+i);
rot(4*x,4*y);
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
for(int i=0;i<16;i++)
{
scanf("%s",c[i]);
}
memset(vis,0,sizeof(vis));
flag=0;
for(int i=0;i<16;i++)
{
for(int j=0;j<16;j++)
{
if(c[i][j]>='0'&&c[i][j]<='9')
a[i][j]=c[i][j]-'0';
else a[i][j]=c[i][j]-'A'+10;
}
}
ans=55555;
dfs(0,0,0);
printf("%d\n",ans);
}
return 0;
}