标签:
2 1 2 3 4 1 2 3 4 1 2 3 4 2 3 4 1 4 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4
1 1
每次改变四个点状态
预估四个都改变正确 则至少需要移动次数为 (ANS+3)/4;
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <string>
#define inf 1<<30
using namespace std;
int get_h(int b[4][4]){
int ans=inf,tmp=0;
for(int i=0;i<4;i++){
bool flag[5];
int cnt=4;
memset(flag,false,sizeof(flag));
for(int j=0;j<4;j++)
if(!flag[b[i][j]]){
cnt--;
flag[b[i][j]]=true;
}
tmp+=3-cnt;
}
ans=min(tmp,ans);
tmp=0;
for(int j=0;j<4;j++){
bool flag[5];
int cnt=4;
memset(flag,false,sizeof(flag));
for(int i=0;i<4;i++)
if(!flag[b[i][j]]){
cnt--;
flag[b[i][j]]=true;
}
tmp+=3-cnt;
}
ans=min(tmp,ans);
return (ans+3)/4;
}
bool dfs(int len,int a[4][4],int kind,int kind1)
{
if(get_h(a)>len) return false ;
if(len==0) return true ;
int aa[4][4];
for(int i=0; i<4; i++)
{
if(kind==i&&kind1==2)
{
;
}
else
{
for(int j=0; j<4; j++)
for(int k=0; k<4; k++)
aa[j][k]=a[j][k];
for(int j=0; j<4; j++)
if(j) aa[i][j]=a[i][j-1];
else aa[i][j]=a[i][3];
if(dfs(len-1,aa,i,1)) return true ;
}
if(kind==i&&kind1==1)
;
else
{
for(int j=0; j<4; j++)
for(int k=0; k<4; k++)
aa[j][k]=a[j][k];
for(int j=0; j<4; j++)
if(j!=3) aa[i][j]=a[i][j+1];
else aa[i][j]=a[i][0];
if(dfs(len-1,aa,i,2)) return true ;
}
if(kind==i&&kind1==3)
{
;
}
else
{
for(int j=0; j<4; j++)
for(int k=0; k<4; k++)
aa[j][k]=a[j][k];
for(int j=0; j<4; j++)
if(j!=3) aa[j][i]=a[j+1][i];
else aa[j][i]=a[0][i];
if(dfs(len-1,aa,i,4)) return true ;
}
if(kind==i&&kind1==4)
{
;
}else
{
for(int j=0; j<4; j++)
for(int k=0; k<4; k++)
aa[j][k]=a[j][k];
for(int j=0; j<4; j++)
if(j) aa[j][i]=a[j-1][i];
else aa[j][i]=a[3][i];
if(dfs(len-1,aa,i,3)) return true ;
}
}
return false ;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int a[4][4];
for(int i=0; i<4; i++)
{
for(int j=0; j<4; j++)
scanf("%d",&a[i][j]);
}
int len;
for(len=get_h(a); len<=5; len++)
{
if(dfs(len,a,-1,-1))
{
printf("%d\n",len);
break;
}
}
if(len>5) printf("-1\n");
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/u013097262/article/details/49721863