标签:
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