HDOJ1728(逃离迷宫)

逃离迷宫

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1139    Accepted Submission(s): 245


Problem 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
 

一开始准备用优先队列做,每次用拐弯最少的点去找,但是WA了n次,根据崔牛的说法

 

 int Visited[N][N];
开2维并不能保证最优性

举个例子,到达某个点的时候方向为向上或者向右的最少转弯次数都是4次
假如终点在向上的方向,那么总的最少转弯次数就是4次
但是开2维数组有可能造成记录的是向右的状态,因为同是4次。
那么这样到达终点就需要5次转弯了。

解决办法
开数组 int Visited[N][N][4];
记录到达每个点当前方向的最小转弯次数

 

后来从学长那边了解到,我只要每次走一行或一列,就能保证每次搜到的就是最优的,无限羡慕我的学长asli

http://www.cppblog.com/Dreams/archive/2009/04/23/80882.html

 

  1//Accepted 1728 31MS 328K 1633 B C++ Xredman 
  2#include <iostream>
  3#include <queue>
  4#define NIL 99999999
  5using namespace std;
  6
  7const int N = 102;
  8
  9struct Point
 10{
 11    int x, y;
 12}
;
 13
 14char graph[N][N];
 15int tcnt[N][N];//记录拐弯次数
 16int m, n, k;
 17
 18int dir[4][2= {{10}{-10}{01}{0-1}};
 19
 20bool isBound(int x, int y)
 21{
 22    if(x < 0 || y < 0)
 23        return false;
 24    if(x >= m || y >= n)
 25        return false;
 26    return true;
 27}

 28
 29int bfs(Point bp, Point ep)
 30{
 31    Point a, b;
 32    queue<Point> Q;
 33    int i, j, k, tk;
 34    
 35    for(i = 0; i < m; i++)
 36        for(j = 0; j < n; j++)
 37            tcnt[i][j] = -1;
 38
 39    Q.push(bp);
 40
 41    while(!Q.empty())
 42    {
 43        a = Q.front();
 44        Q.pop();
 45
 46        tk = tcnt[a.x][a.y] + 1;
 47
 48        for(i = 0; i < 4; i++)
 49        {
 50            b.x = a.x + dir[i][0];
 51            b.y = a.y + dir[i][1];
 52
 53            while(isBound(b.x, b.y) && graph[b.x][b.y] == '.')
 54            {
 55                if(tcnt[b.x][b.y] == -1)
 56                {
 57                    if(b.x == ep.x && b.y == ep.y)
 58                        return tk;
 59                    else
 60                    {
 61                        tcnt[b.x][b.y] = tk;
 62                        Q.push(b);
 63                    }

 64                }

 65                b.x += dir[i][0];
 66                b.y += dir[i][1];
 67            }

 68            
 69        }

 70    }

 71    return -1;
 72}

 73int main()
 74{
 75    int T;
 76    int i, ans;
 77    Point bp, ep;
 78    cin>>T;
 79    while(T--)
 80    {
 81        cin>>m>>n;
 82        for(i = 0; i < m; i++)
 83            cin>>graph[i];
 84
 85        cin>>k>>bp.y>>bp.x>>ep.y>>ep.x;
 86        if(bp.x == ep.x && bp.y == ep.y)
 87        {
 88            cout<<"yes"<<endl;
 89            continue;
 90        }

 91
 92        bp.x--; bp.y--;
 93        ep.x--; ep.y--;
 94        ans = bfs(bp, ep);
 95
 96        if( ans == -1 || ans > k)
 97            cout<<"no"<<endl;
 98        else 
 99            cout<<"yes"<<endl;
100    }

101    return 0;
102}

103/*
1043
1055 5
106**
107*.**.
108..
109..
110*.
1112 1 1 1 3
112>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1135
1145 5
115**
116*.**.
117..
118..
119*.
1201 1 1 5 2
121*/

122

 

posted on 2009-04-25 09:15  Xredman  阅读(371)  评论(0编辑  收藏  举报

导航