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;
}