zoukankan      html  css  js  c++  java
  • HDU 1728 逃离迷宫

    题目链接:HDU 1728

    Description

    给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地方是障碍,她必须绕行,从迷宫的一个位置,只能走到与它相邻的4个位置中,当然在行走过程中,gloria不能走到迷宫外面去。令人头痛的是,gloria是个没什么方向感的人,因此,她在行走过程中,不能转太多弯了,否则她会晕倒的。我们假定给定的两个位置都是空地,初始时,gloria所面向的方向未定,她可以选择4个方向的任何一个出发,而不算成一次转弯。gloria能从一个位置走到另外一个位置吗?

    Input

    第1行为一个整数t (1 ≤ t ≤ 100),表示测试数据的个数,接下来为t组测试数据,每组测试数据中,第1行为两个整数m, n (1 ≤ m, n ≤ 100),分别表示迷宫的行数和列数,接下来m行,每行包括n个字符,其中字符'.'表示该位置为空地,字符'*'表示该位置为障碍,输入数据中只有这两种字符,每组测试数据的最后一行为5个整数k, x1, y1, x2, y2 (1 ≤ k ≤ 10, 1 ≤ x1, x2 ≤ n, 1 ≤ y1, y2 ≤ m),其中k表示gloria最多能转的弯数,(x1, y1), (x2, y2)表示两个位置,其中x1,x2对应列,y1, y2对应行。

    Output

    每组测试数据对应为一行,若gloria能从一个位置走到另外一个位置,输出“yes”,否则输出“no”。

    Sample Input

    2
    5 5
    ...**
    *.**.
    .....
    .....
    *....
    1 1 1 1 3
    5 5
    ...**
    *.**.
    .....
    .....
    *....
    2 1 1 1 3

    Sample Output

    no
    yes

    题意

    输入一个迷宫,起点、终点以及最大可以转弯的次数k,问在不超过k次转弯的情况下能否逃离迷宫。

    题解:

    迷宫问题,用BFS做,计算到每个块儿最少的转弯次数,初始化为INF,如果更新就把这个点入队,当然初始把起点周围4个可以走的点入队,转弯次数都设为0,然后判断终点的最少转弯次数是否符合条件就行了。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int inf = 1000000;
    char map[110][110];
    int vis[110][110];//记录点的最优解;
    int k, x1, x2, yy, y2, flag, m, n;
    int dir[4][2] = { { 1, 0 },{ -1, 0 },{ 0, 1 },{ 0, -1 } };
    
    struct node
    {
    	int x, y;
    	int num;//次数
    	int dir;//这个点由哪个方向来的;
    };
    
    bool cheak(int x, int y)//判断是否满足范围;
    {
    	if (x >= 0 && x < m && y >= 0 && y < n && map[x][y] != '*')
    		return true;
    	return false;
    }
    
    void bfs()
    {
    	queue<node>q;
    	node temp, type;
    	temp.x = x1;
    	temp.y = yy;
    	temp.num = -1;
    	temp.dir = -1;
    	q.push(temp);
    	while (!q.empty())
    	{
    		temp = q.front();
    		q.pop();
    		if (temp.x == x2 && temp.y == y2 && temp.num <= k)
    		{
    			flag = 1;
    			return;
    		}
    		for (int i = 0; i < 4; i++)
    		{
    			int fx = temp.x + dir[i][0];
    			int fy = temp.y + dir[i][1];
    			if (cheak(fx, fy))
    			{
    				if (temp.dir == -1)//开始 
    				{
    					type.dir = i;
    					type.num = 0;
    					type.x = fx;
    					type.y = fy;
    					if (vis[fx][fy] >= type.num)
    					{
    						vis[fx][fy] = temp.num;
    						q.push(type);
    					}
    				}
    				else
    				{
    					if (i == temp.dir)//新的坐标和它的上个比较,如果相同就不转弯;
    					{
    						type.dir = i;
    						type.num = temp.num;
    						type.x = fx;
    						type.y = fy;
    						if (type.num <= vis[fx][fy])
    						{
    							vis[fx][fy] = type.num;
    							q.push(type);
    						}
    					}
    					else
    					{
    						type.dir = i;
    						type.num = temp.num + 1;
    						type.x = fx;
    						type.y = fy;
    						if (type.num <= vis[fx][fy])
    						{
    							vis[fx][fy] = type.num;
    							q.push(type);
    						}
    					}
    				}
    			}
    		}
    	}
    	return;
    }
    
    int main()
    {
    	int t;
    	cin >> t;
    	while (t--)
    	{
    		cin >> m >> n;
    		for (int i = 0; i < m; i++)
    			cin >> map[i];
    		for (int i = 0; i < m; i++)
    			for (int j = 0; j < n; j++)
    				vis[i][j] = inf;
    		cin >> k >> yy >> x1 >> y2 >> x2;
    		x1 -= 1;//因为 图是按0开始的
    		x2 -= 1;
    		yy -= 1;
    		y2 -= 1;
    		flag = -1;
    		if (x1 == x2 && yy == y2)
    		{
    			cout << "yes" << endl;
    			continue;
    		}
    		bfs();
    
    		if (flag == -1)
    			cout << "no" << endl;
    		else
    			cout << "yes" << endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    MAC记住 git的用户名密码
    webpack初学踩坑记
    __dirname和__filename和process.cwd()三者的区别
    webpack
    日期格式在ios中的兼容性
    php实现导出excel功能
    node 之koa项目学习
    nodejs之socket.io 私发消息和选择群组发消息
    nodejs之socket.io 聊天实现
    mongoDB基础语法
  • 原文地址:https://www.cnblogs.com/Titordong/p/9592477.html
Copyright © 2011-2022 走看看