1.思路
若初使或者最终状态不在中间的16格上将其交换至16格上,然后判断即可。
思维定式了,比赛时居然还跑了个IDA*,果断去超时,赛后还是队友发现是多余的,这么明显都没看出来,真是傻X了!!!
2.代码
#include<cstdio> #include<cstring> #include<vector> #include<iostream> using namespace std; int idx[24]; void init(int *first,int *last,int *maze,int &org,int &dest) { int i;int cur=0; for(i=3;i<=20;i++) { if(!last[i])dest=cur; idx[last[i]]=cur++; if(i==6||i==15)i++; } int j; for(i=3,j=0;j<16;j++,i++) { maze[j]=idx[first[i]]; if(!first[i])org=j; if(i==6||i==15)i++; } } bool isResolve(int *maze,int org,int dest) { int s=abs(double(org/4-dest/4))+abs(double(org%4-dest%4)); for(int i=0; i<16; i++) { for(int j=0; j<i; j++) { if(maze[j]>maze[i]) s++; } } if(s&1)return false; else return true; } int vex[8]={0,1,2,7,16,21,22,23}; bool inVex(int pos) { for(int i=0;i<8;i++)if(vex[i]==pos)return true; return false; } bool isVex(int *first,int *last) { for(int i=0;i<8;i++)if(first[vex[i]]!=last[vex[i]])return false; return true; } int getNext(int pos) { if(pos==0||pos==2)return 3; if(pos==1||pos==7)return 6; if(pos==16||pos==22)return 17; return 20; } int main() { #ifndef ONLINE_JUDGE freopen("data.in", "r", stdin); //freopen("data.out","w",stdout); #endif int maze[16]; int first[24],last[24],st,ed; int cases; cin>>cases; while(cases--) { int i; for(i=0;i<24;i++) { scanf("%d",first+i); if(first[i]==0)st=i; } for(i=0;i<24;i++) { scanf("%d",last+i); if(last[i]==0)ed=i; } if(inVex(st))swap(first[st],first[getNext(st)]); if(inVex(ed))swap(last[ed],last[getNext(ed)]); if(!isVex(first,last)) { printf("Y\n");continue; } int org,dest; init(first,last,maze,org,dest); if(isResolve(maze,org,dest))printf("N\n"); else printf("Y\n"); } return 0; }