USACO 玉米田迷宫 Corn Maze

移步到新Blog查看图片 (此Blog已废弃,图片已失效)




这题是一个大坑。

首先我们想到了BFS,这个题就是一个简单到不能再简单的Maze加上传送门就是了。

但是有一点是传送门不费时啊!!什么鬼。所以我们要先判传送门

为什么呢?我记得有一组测试数据包括了这种情况


这不清真

另外,好像还有一个点是全都是传送门的情况。


判传送门(并不是判队首元素位于传送门,而是队首坐标移动之后),传送过去之后耗时不加,队列保存传送后的位置,这样就不会产生无限传送死循环的问题。

但是关于情况2怎么办?我们利用BFS的性质,把传送门(传过去之后)打上标记,然后就不用他了。(每一次用都是最早用他)

传送门I hate you


读入的时候记录传送门的相对坐标,像这样:

scanf("%s",&mapx[i]);
		for (int j=0;j='A' && mapx[i][j]<='Z')
			{
				if (toit[mapx[i][j]-65][0][0]==-1)
				{
					toit[mapx[i][j]-65][0][0]=i; toit[mapx[i][j]-65][0][1]=j;
				}
				else toit[mapx[i][j]-65][1][0]=i; toit[mapx[i][j]-65][1][1]=j;
			}
		}
之后碰到传送门直接查表。,顺便记下起点sxsy和重点exey

#include
#include
#include
#include
#include
#include
#include
using namespace std;

queuequex,quey;
int cachex,cachey;
char mapx[400][400]={0};
int sx,sy,ex,ey,n,m;
int head=0,tail=1;
int timex[100000]={0},toit[50][2][2];
bool checked[400][400]={false};
int wayx[4]={-1,0,1,0},wayy[4]={0,1,0,-1};

int main()
{
	memset(toit,-1,sizeof(toit));
	scanf("%d%d",&n,&m);
	for (int i=0;i='A' && mapx[i][j]<='Z')
			{
				if (toit[mapx[i][j]-65][0][0]==-1) toit[mapx[i][j]-65][0][0]=i; toit[mapx[i][j]-65][0][1]=j;
				else toit[mapx[i][j]-65][1][0]=i; toit[mapx[i][j]-65][1][1]=j;
			}
		}
	}

	quex.push(sx); quey.push(sy);
	timex[1]=0;
	while (quex.size()>0)
	{
		head++;
		cachex=quex.front(); cachey=quey.front();
		if (mapx[cachex][cachey]=='=')
		{
			printf("%d\n",timex[head]);
			return 0;
		}
		for (int i=0;i<=3;i++)
			if (cachex+wayx[i]>=0 && cachex+wayx[i]=0 && cachey+wayy[i]='A' && mapx[cachex+wayx[i]][cachey+wayy[i]]<='Z' && checked[cachex+wayx[i]][cachey+wayy[i]]==false)
				{
					if (cachex+wayx[i]==toit[mapx[cachex+wayx[i]][cachey+wayy[i]]-65][0][0] && cachey+wayy[i]==toit[mapx[cachex+wayx[i]][cachey+wayy[i]]-65][0][1])
					{
						tail++;
						quex.push(toit[mapx[cachex+wayx[i]][cachey+wayy[i]]-65][1][0]); quey.push(toit[mapx[cachex+wayx[i]][cachey+wayy[i]]-65][1][1]);
						timex[tail]=timex[head]+1;
						checked[cachex+wayx[i]][cachey+wayy[i]]=true;
						//cout<<"A  "<<"X= "<其实这个题处理好了传送门,你会发现,其实不难……(输出调试大法好)

记得用checked数组标记已经访问的点和传送门,要不无限使用传送门


你可能感兴趣的:(USACO,bfs,题解,洛谷,OI)