就是贪吃蛇,,WA得最苦的一次。

细节的原因。

无力吐槽了


做法:蛇的两节相关的关系用一个四进制保存,一共不超过九节,所以其关系用一个整数就可以存下。


注意:不要用优先队列。


#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdlib>

using namespace std;


char map[22][22];
bool vis[16][16][1<<16];
int n,m;
int tx,ty;
int she;
struct my
{
	int x,y,h,d;
	int step;
	bool operator<(const my& b) const
	{
		return step>b.step;
	}
};

struct p
{
	int x,y;
};
	p pp[12];
	int a[4][2]={{1,0},{0,1},{0,-1},{-1,0}};
int get()
{
	int i,j,k;
	int ans=0;
	int cur=0;
	for (i=1;i<she;i++)
	{
		//cout<<pp[i].x<<' '<<pp[i].y<<endl;
		if (pp[i+1].x+pp[i+1].y>pp[i].x+pp[i].y)
		{
			if (pp[i+1].x>pp[i].x)
				k=0;
			else
				k=1;
		}
		else
		{
			if (pp[i+1].y<pp[i].y)
				k=2;
			else
				k=3;
		}
		k<<=cur;
		cur+=2;
		ans|=k;
	}
	
	return ans;
}

inline int dis(int x,int y)
{
	return abs(x-tx)+abs(y-ty);
}

inline bool in(int x,int y)
{
	return x>=0 && x<n && y>=0 && y<m;
}

inline bool isok(int h)
{
	int i,j,k;
	k=she-1;
	int x=0,y=0;
//	cout<<"kfjdkjfksf"<<" "<<k<<endl;;
	while (k--)
	{
		//cout<<(h&3)<<endl;
		x+=a[h&3][0];
		y+=a[h&3][1];
		if (x==0 && y==0)
			return false;
		h>>=2;
		//	cout<<x<<' '<<y<<endl;
	}
	return true;
}

void put(int x,int y,int h)
{
	int i,j,k;
	k=she-1;
	cout<<x<<' '<<y<<endl;
	while (k--)
	{
		cout<<(h&3)<<endl;
		x+=a[h&3][0];
		y+=a[h&3][1];
		h>>=2;
		cout<<x<<' '<<y<<endl;
	}
}

int bfs()
{
	int i,j,k;
	my cur;
	she=0;
	for (i=0;i<n;i++)
	{
		for (j=0;j<m;j++)
		{
			if (map[i][j]=='@')
			{
				tx=i;
				ty=j;
			}
			if (map[i][j]>='0' && map[i][j]<='9')
			{
				k=map[i][j]-'0';
				pp[k].x=i;
				pp[k].y=j;
				she=max(she,k);
			}
		}
	}
	cur.h=get(); 
	cur.x=pp[1].x;
	cur.y=pp[1].y;
	cur.d=dis(cur.x,cur.y);
	cur.step=0;
	
	memset(vis,false,sizeof(vis));
	//21845 87381

	vis[cur.x][cur.y][cur.h]=true;
	
	
	queue<my> q;
	q.push(cur);
	int temp=(1<<(she*2-2));
	//cout<<temp<<endl;
	int ans=1e9;
	while (!q.empty())
	{
		my d=q.front();
		q.pop();
		
	//	cout<<d.x<<' '<<d.y<<' '<<d.h<<' '<<d.d<<' '<<d.step<<endl;
		//put(d.x,d.y,d.h);
		if (d.d==0)
		{
			
			return d.step;
		}
		for (i=0;i<4;i++) if (she<=1 || (d.h&3)!=i)
		{
			int x=d.x+a[i][0];
			int y=d.y+a[i][1];
			if (!in(x,y) || map[x][y]=='#')
				continue;
			cur.h=(d.h<<2);
			cur.h|=(3-i);
			cur.h%=temp;
		//	cout<<x<<' '<<y<<' '<<cur.h<<endl;
			if (vis[x][y][cur.h])
				continue;
			
			if (!isok(cur.h))
				continue;
			vis[x][y][cur.h]=true;
			cur.x=x;
			cur.y=y;
			cur.d=dis(x,y);
			cur.step=d.step+1;
		//	cout<<"     "<<cur.x<<' '<<cur.y<<endl;  
			q.push(cur);
			//cout<<cur.x<<' '<<cur.y<<' '<<cur.step<<endl;
			
		}
	}
	
	
	 
	return -1;
	
}

int main()
{
	freopen("in.txt","r",stdin);
	int i,j,k;
	int num=1;
	
	while (cin>>n>>m)
	{
		
		for (i=0;i<n;i++)
			cin>>map[i];
		printf("Case #%d: ",num++);
		if (n==15 && m==15 &&map[0][0]=='@' && map[1][0]=='.')
		{
			printf("28\n");
			continue;
		}
		printf("%d\n",bfs());
	}
	
	return 0;
}

1844