HDU 3137 No Left Turns广搜+标记方向

题意:有一个哥们从起点S前往终点F,走一条路,但是这哥们只有右转(相对于地图中的人物的右转不是二维地图一直往右走),问走到终点需要多长时间,每走一格,时间加一。

想法:首先涉及到转弯,方向数组个规格化很重要dir[] = {上, 右, 下, 左},这么一来我在一个地方右转就是(dir + 1)%4即可。然后会有人开始会觉得那么我只要将直走情况和右转走一格情况推入队列中让他处理就完事了,答案是可以的。但是会超出存储空间限制,这里超的不是因为地图开的大了,而是因为队列里面存储的边太多了,因为不能标记走过的方块不能走,那么这样一来问题就出现了,如果一个人在一个地方四下都能走,然后一直右转一直右转,然后推入队列,这样这个哥们就会在一个“田”字形的图里面无限制的往队列里面推入数据,直到终点被搜到。

           那么现在的问题就是如何不让这种“田”字循环或者其他的循环推入队列呢?很显然,我们可以纪录每一个格子上面的已经走过一次的方向,如果这个格子的这个方向被走过了,那么再走这个格子的这个方向不是增加了队列的负担了吗,所以遇到同一格子的不同方向可以走,遇到同一格子的不同方向不可以走,这样既节省时间右优化了存储空间问题。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
const int max_size = 30;
const int inf = 0x7fffffff;
int N, c, r;
char map[max_size][max_size];
int dir[4][2] = {-1, 0, 0, 1, 1, 0, 0, -1};
struct node{
	int x;
	int y;
	int tims;
	int direction;
};
node st, ed;

void _init()
{
	memset(map, '\0', sizeof(map));
}

int BFS(int org_dir)
{
	struct node cur, nxt;
	int mark_cnt[max_size][max_size];
	queue<node>q;
	while(!q.empty()) q.pop();
	memset(mark_cnt, -1, sizeof(mark_cnt));
	st.direction = org_dir;
	st.tims = 0;
	mark_cnt[st.x][st.y] = st.direction;
	q.push(st);
	while(!q.empty()){
		cur = q.front();
		q.pop();
		if(cur.x == ed.x && cur.y == ed.y){
			return cur.tims;
		}
		//直走
		nxt.x = cur.x + dir[cur.direction][0];
		nxt.y = cur.y + dir[cur.direction][1];
		nxt.direction = cur.direction;
		if(nxt.direction != mark_cnt[nxt.x][nxt.y] && map[nxt.x][nxt.y] != 'X'){
			mark_cnt[nxt.x][nxt.y] = nxt.direction;
			nxt.tims = cur.tims + 1;
			q.push(nxt);
		}
		//右转
		nxt.direction = (cur.direction + 1) % 4; 
		nxt.x = cur.x + dir[nxt.direction][0];
		nxt.y = cur.y + dir[nxt.direction][1];
		if(nxt.direction != mark_cnt[nxt.x][nxt.y] && map[nxt.x][nxt.y] != 'X'){
			nxt.tims = cur.tims + 1;
			mark_cnt[nxt.x][nxt.y] = nxt.direction;
			q.push(nxt);
		}
	}
	return -1;
}
int main()
{
	cin>>N;
	while(N--){
		cin>>r>>c;
		_init();
		getchar();
		for(int i = 1; i <= r; ++i){
			gets(map[i] + 1); 
			for(int j = 1; j <= c; ++j){
				if(map[i][j] == 'S'){
					st.x = i;
					st.y = j;		
				}
				else if(map[i][j] == 'F'){
					ed.x = i;
					ed.y = j;
				}
			}
		}
		
		int ans = inf;
		for(int i = 0; i <= 3; ++i){
			int steps = BFS(i);
			if(steps != -1 && steps < ans){
				ans = steps;
			} 
		}
		cout<<ans<<endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/triple_wdf/article/details/80563032
今日推荐