题目:http://acm.hdu.edu.cn/showproblem.php?pid=6341
思路:
预处理每一个4*4 格子旋转的四种状态。
然后dfs即可,时间上限4^(16) 但是实际上
数独限制较多,大多数情况中途已经剪掉。
代码:
#include<bits/stdc++.h>
using namespace std;
char txt[20][20];
int a[5][4][4][4][4],ans;
bool L[20][20],R[20][20];
void init()
{
for(int i=0; i<16; i++)
{
for(int j=0; j<16; j++)
{
int c;
if(txt[i][j]>='0'&&txt[i][j]<='9')
c=txt[i][j]-'0';
else
c=txt[i][j]-'A'+10;
a[0][i/4][j/4][i%4][j%4]=c;
a[4][i/4][j/4][i%4][j%4]=c;
}
}
for(int k=1; k<4; k++)
for(int i=0; i<4; i++)
for(int j=0; j<4; j++)
for(int x=0; x<4; x++)
for(int y=0; y<4; y++)
a[k][i][j][x][y]=a[k-1][i][j][3-y][x];
}
bool check(int x,int y,int k)
{
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
int c=a[k][x][y][i][j];
if(L[x*4+i][c]) return 0;
if(R[y*4+j][c]) return 0;
}
}
return 1;
}
void change(int x,int y,int k,bool C)
{
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
int c=a[k][x][y][i][j];
L[x*4+i][c]=C;
R[y*4+j][c]=C;
}
}
}
void dfs(int x,int y,int step)
{
if(step>=ans) return;
if(x==4)
{
ans=min(ans,step);
return;
}
for(int i=0;i<4;i++)
{
if(check(x,y,i))
{
change(x,y,i,1);
if(y<3) dfs(x,y+1,step+i);
else dfs(x+1,0,step+i);
change(x,y,i,0);
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
for(int i=0; i<16; i++)
scanf("%s",&txt[i]);
init();
memset(L,0,sizeof(L));
memset(R,0,sizeof(R));
ans=1e9;
dfs(0,0,0);
printf("%d\n",ans);
}
return 0;
}