hdu 5094 Maze bfs

传送门:上海邀请赛E

给定一个n×m的迷宫,给出相邻格子之间的墙或者门的信息,墙说明不可走,如果是门则需要有对应的钥匙才能通过,问是否能够从(1,1)到达(n,m)


一个带状态的bfs,再另记一个状态表示所带钥匙的种类,钥匙种类数最多只有10,因此可以用位来表示钥匙的状态。

/******************************************************
 * File Name:   5094.cpp
 * Author:      kojimai
 * Create Time: 2014年11月03日 星期一 09时24分27秒
 ******************************************************/

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
#define FFF 55
bool vis[FFF][FFF][2048];
int map[FFF][FFF],road[FFF][FFF][4];
int move[4][2] ={-1,0,0,1,1,0,0,-1};//0-up 1-right 2-down 3-left
struct node
{
	int x,y,t,key;
}now,tmp;
queue<node> pp;

int getg(int g)
{
	if(g == 0)
		return -1;
	else
		return 1 << g;
}
void solve(int x1,int y1,int x2,int y2,int g)
{
	if(x1 == x2)
	{
		if(y1<y2)
		{
			road[x1][y1][1] = getg(g);
			road[x2][y2][3] = getg(g);
		}
		else
		{
			road[x1][y1][3] = getg(g);
			road[x2][y2][1] = getg(g);
		}
	}
	else if(x1 < x2)
	{
		road[x1][y1][2] = getg(g);
		road[x2][y2][0] = getg(g);
	}
	else
	{
		road[x1][y1][0] = getg(g);
		road[x2][y2][2] = getg(g);
	}
	return;
}
bool judge(int dir)
{
	if(road[now.x][now.y][dir] == -1)
		return false;
	if(road[now.x][now.y][dir] == 0)
		return true;
	if((road[now.x][now.y][dir] & now.key) == 0)
		return false;
	else
		return true;
}
void printr()
{
	for(int k = 0;k <= 3;k++)
	{
		cout<<" "<<k<<endl;
		for(int i = 1;i <= 4;i++)
		{
			for(int j = 1;j <= 4;j++)
			{
				cout<<road[i][j][k]<<' ';
			}
			cout<<endl;
		}
	}
}
void printm()
{
	for(int i = 1;i <=  4;i++)
	{
		for(int j = 1;j <= 4;j++)
		{
			cout<<map[i][j]<<' ';
		}
		cout<<endl;
	}
}

int main()
{
	int n,m,p,s,x1,x2,y1,y2,g,k,key;
	while(~scanf("%d",&n))
	{
		while(!pp.empty()) pp.pop();
		scanf("%d%d",&m,&p);
		scanf("%d",&k);
		memset(map,0,sizeof(map));
		memset(road,0,sizeof(road));
		while(k--)
		{
			scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&g);
			solve(x1,y1,x2,y2,g);
		}
		scanf("%d",&s);
		while(s--)
		{
			scanf("%d%d%d",&x1,&y1,&key);
			map[x1][y1] |= (1<<key);
		}
		memset(vis,false,sizeof(vis));
		int ans = -1;
		now.x = 1;now.y = 1;now.key = map[1][1];now.t = 0;
		vis[1][1][now.key] = true;
		pp.push(now);
		//printr();
		//printm();
		while(!pp.empty())
		{
			now = pp.front();pp.pop();
			//cout<<" x = "<<now.x<<" y = "<<now.y<<" t = "<<now.t<<" key = "<<now.key<<endl;
			if(now.x == n&&now.y == m)
			{
				ans = now.t;
				break;
			}
			tmp.t = now.t + 1;
			int xx,yy;
			for(int i = 0;i < 4;i++)
			{
				if(judge(i))
				{
					xx = now.x + move[i][0];
					yy = now.y + move[i][1];
					if(xx <= 0 || xx > n || yy <= 0 || yy > m)
						continue;
					else
					{
						tmp.key = now.key | map[xx][yy];
						tmp.x = xx;
						tmp.y = yy;
						if(!vis[tmp.x][tmp.y][tmp.key])
						{
							vis[tmp.x][tmp.y][tmp.key] = true;
							pp.push(tmp);
						}	
					}
				}
			}
		}	
		cout<<ans<<endl;
	}
	return 0;
}
相关文章
相关标签/搜索