hdoj4021(24 puzzle)

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


你可能感兴趣的:(hdoj4021(24 puzzle))