POJ 3083 Children of the Candy Corn

题意:有一个迷宫,然后起点和终点在四边上,然后边上除了起点和终点都是墙,从s走到e有三种策略,第一种,左手摸墙策略:左手放在墙壁上,然后手不离墙壁,沿着大拇指方向走,必定能走到终点,然后计算这种走法的步数。第二种,右手摸墙策略:右手放在墙壁上,然后手不离墙壁,沿着大拇指方向走,必定能走到终点,然后计算这种走法的不熟。第三种,最短路径。

然后输出三种策略的行走长度。

思想:首先,直接先点名一个坑点,如果无法从s走到e直接不输出,虽然题目中表明了,总能从s走到e。

其次,s走到e,左手扶墙策略和从e走到s,右手扶墙策略是一回事。

最后,就是主要步骤了,先规定方向:上0右1下2左3,然后dir方向数组也要按照上右下左存储。

当按照原来方向向前一步走,如果此时的左手边是墙,那么就保持方向不变,继续前行;

当按照原来方向向前一步走,如果此时的左手边不是墙,那么显然就要进行左转弯,改变方向为(原来方向 + 3) % 4,然后再在转向后向前一步走;

当按照原来方向向前一步走,如果走到了墙上,也就是不能走了,就要进行右转弯,改变方向为(原来方向 + 1) % 4,不用走动,转向即可。

按照上述三种情况,采用队列结构即可。至于最短路非常简单BFS搜到即可输出。

//直走,左前方有wall,启动直走 
//直走,左前方没有wall,启动左转
//直走,前方有wall,启动右转
//上0下2左3右1 
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int h,w;
char map[45][45];
struct NODE{
	int x,y;
	int dir;
	int steps;
}; 
struct NODE s_node,e_node;
int dir[4][2] = {-1,0,0,1,1,0,0,-1};

int WalkBFS()
{
	struct NODE node = s_node;
	int minstep = 0;
	bool visit[45][45];
	queue<NODE>q;
	while(!q.empty()) q.pop();
	memset(visit,false,sizeof(visit));
	visit[node.x][node.y] = true;
	node.steps = 1;
	q.push(node);
	while(!q.empty()){
		node = q.front();
		q.pop();
		for(int k = 0;k <= 3; ++k){
			NODE nxt_node;
			nxt_node.x = node.x + dir[k][0];
			nxt_node.y = node.y + dir[k][1];
			if(map[nxt_node.x][nxt_node.y] == '.' && nxt_node.x >= 1 && nxt_node.x <= h && nxt_node.y >= 1 
			   && node.y <= w && !visit[nxt_node.x][nxt_node.y]){
			   	//printf("(%d,%d)\n",nxt_node.x,nxt_node.y);
			   	nxt_node.steps = node.steps + 1;
			   	visit[nxt_node.x][nxt_node.y] = true;
			   	if(nxt_node.x == e_node.x && nxt_node.y == e_node.y){
			   		return nxt_node.steps;
			   	}
			   	q.push(nxt_node);
			} 
		}
	}
	return -1; 
}
void PUT(int x,int y,int dir)
{
	char str[10];
	if(dir == 0) strcpy(str,"上");
	else if(dir == 1) strcpy(str,"右");
	else if(dir == 2) strcpy(str,"下");
	else strcpy(str,"左");
	printf("(%d,%d,%s)\n",x,y,str); 
}
int Walk_LEFT_BFS(int MARK)
{
	NODE snode,enode;
	queue<NODE>q;
	while(!q.empty()) q.pop();
	if(MARK){
		snode = s_node;
		enode = e_node;
	}
	else{
		snode = e_node;
		enode = s_node;
	}
	snode.steps = 1;
	q.push(snode);
	while(!q.empty()){
		snode = q.front();
		q.pop(); 
		//PUT(snode.x,snode.y,snode.dir);
		if(snode.x == enode.x && snode.y == enode.y){
			return snode.steps;
		}
		NODE nxtnode;
		nxtnode.x = snode.x + dir[snode.dir][0];
		nxtnode.y = snode.y + dir[snode.dir][1];
		if(map[nxtnode.x][nxtnode.y] == '#'){
			snode.dir = (snode.dir + 1) % 4;//TURN RIGHT 
			q.push(snode);
		}
		else if(map[nxtnode.x][nxtnode.y] == '.' && map[nxtnode.x + dir[(snode.dir + 3) % 4][0]][nxtnode.y + dir[(snode.dir + 3) % 4][1]] == '#'){
			nxtnode.dir = snode.dir;
			nxtnode.steps = snode.steps + 1;
			q.push(nxtnode);
		}
		else if(map[nxtnode.x][nxtnode.y] == '.' && map[nxtnode.x + dir[(snode.dir + 3) % 4][0]][nxtnode.y + dir[(snode.dir + 3) % 4][1]] == '.'){
			nxtnode.dir = (snode.dir + 3) % 4;//TURN LEFT
			//左转
			nxtnode.x += dir[nxtnode.dir][0];
			nxtnode.y += dir[nxtnode.dir][1];
			nxtnode.steps = snode.steps + 2;
			q.push(nxtnode); 
		} 
	}
	return -1;
}
int main()
{
	int T;
	scanf("%d",&T);
	while(T--){
		memset(map,'\0',sizeof(map));
		scanf("%d%d",&w,&h);
		for(int i = 1;i <= h; ++i){
			scanf("%s",map[i]+1);
		}
		for(int i = 1;i <= h; ++i){
			for(int j = 1;j <= w; ++j){
				if(map[i][j] == 'S'){
					map[i][j] = '.';
					s_node.x = i;
					s_node.y = j;
					if(i == 1){
						s_node.dir = 2;
					}
					else if(i == h){
						s_node.dir = 0;
					}
					else if(j == 1){
						s_node.dir = 1;
					}
					else if(j == w){
						s_node.dir = 3;
					}
				} 
				if(map[i][j] == 'E'){
					map[i][j] = '.';
					e_node.x = i;
					e_node.y = j;
					if(i == 1){
						e_node.dir = 2;
					}
					else if(i == h){
						e_node.dir = 0;
					}
					else if(j == 1){
						e_node.dir = 1;
					}
					else if(j == w){
						e_node.dir = 3;
					}
				}
			}
		}
		int lft_step = Walk_LEFT_BFS(1);
		int rht_step = Walk_LEFT_BFS(0);
		int min_step = WalkBFS();
		//printf("%d\n",min_step);
		if(lft_step == -1) continue;
		printf("%d %d %d\n",lft_step,rht_step,min_step);
	}
	return 0;
} 
/*
2
8 8
########
#......#
#.####.#
#.####.#
#.####.#
#.####.#
#...#..#
#S#E####
9 5
#########
#.#.#.#.#
S.......E
#.#.#.#.#
#########
*/



猜你喜欢

转载自blog.csdn.net/triple_wdf/article/details/80135352