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

    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

    Source

    “网新恩普杯”杭州电子科技大学程序设计邀请赛
     
     
    先上一段TLE代码
     1 #include<iostream>
     2 #include<queue>
     3 #include<cstring>
     4 using namespace std;
     5 int n,m,T,ex,ey;//T表示最大转弯次数,e表示终点
     6 char a[105][105];
     7 int rx[]={0,0,1,-1};
     8 int ry[]={1,-1,0,0};
     9 bool vis[105][105];
    10 struct node
    11 {
    12     int x,y,turn,dir;//turn表示次数,dir表示方向
    13 }per;
    14 bool check(node b)
    15 {
    16     if(b.x>=1&&b.x<=n&&b.y>=1&&b.y<=m&&a[b.x][b.y]!='*')
    17         if(!vis[b.x][b.y])
    18             if(b.turn<=T)
    19                 return true;
    20     return false;
    21 }
    22 bool bfs()
    23 {
    24     queue<node>Q;
    25     Q.push(per);
    26     node cur,next;
    27     while(!Q.empty())
    28     {
    29         cur=Q.front();
    30         Q.pop();
    31         vis[cur.x][cur.y]=true;
    32         if(cur.x==ex&&cur.y==ey&&cur.turn<=T)
    33             return true;
    34         if(cur.turn>T)
    35             break;
    36         for(int i=0;i<4;i++)
    37         {
    38             next.x=cur.x+rx[i];
    39             next.y=cur.y+ry[i];
    40             next.dir=i;
    41             next.turn=cur.turn;
    42             if(next.dir!=cur.dir&&cur.dir!=-1)
    43                 next.turn++;
    44             if(check(next))
    45                 Q.push(next);
    46         }
    47     }
    48     return false;
    49 }
    50 int main()
    51 {
    52     int K;
    53     cin>>K;
    54     while(K--)
    55     {
    56         cin>>n>>m;
    57         for(int i=1;i<=n;i++)
    58         {
    59             for(int j=1;j<=m;j++)
    60             {
    61                 cin>>a[i][j];
    62             }
    63         }
    64         cin>>T>>per.y>>per.x>>ey>>ex;//这里注意是先列后行
    65         per.turn=0;
    66         per.dir=-1;
    67         memset(vis,false,sizeof(vis));
    68         if(bfs())cout<<"yes"<<endl;
    69         else cout<<"no"<<endl;
    70     }
    71     return 0;
    72 }

     因为以转弯数为判断条件,所以要尽量少地改变方向,就像之前做迷宫以步数为条件时,尽可能地减少步数一样,所以采取在一个方向上搜到底的方法。

    AC代码如下,就是上面直接改了一下,有些不必要的码也在里面懒得改orz

     1 #include<iostream>
     2 #include<queue>
     3 #include<cstring>
     4 using namespace std;
     5 int n,m,T,ex,ey;//T表示最大转弯次数,e表示终点
     6 char a[105][105];
     7 int rx[]={0,0,1,-1};
     8 int ry[]={1,-1,0,0};
     9 bool vis[105][105];
    10 struct node
    11 {
    12     int x,y,turn,dir;//turn表示次数,dir表示方向
    13 }per;
    14 bool check(node b)
    15 {
    16     if(b.x>=1&&b.x<=n&&b.y>=1&&b.y<=m&&a[b.x][b.y]!='*')
    17         if(!vis[b.x][b.y])
    18             if(b.turn<=T)
    19                 return true;
    20     return false;
    21 }
    22 bool bfs()
    23 {
    24     queue<node>Q;
    25     Q.push(per);
    26     node cur,next;
    27     while(!Q.empty())
    28     {
    29         cur=Q.front();
    30         Q.pop();
    31         vis[cur.x][cur.y]=true;
    32         if(cur.x==ex&&cur.y==ey&&cur.turn<=T)
    33             return true;
    34         if(cur.turn>T)
    35             break;
    36         for(int i=0;i<4;i++)
    37         {
    38             next.x=cur.x+rx[i];
    39             next.y=cur.y+ry[i];
    40             next.dir=i;
    41             next.turn=cur.turn;
    42             if(next.dir!=cur.dir&&cur.dir!=-1)
    43                 next.turn++;
    44             while(check(next))//一个方向搜到底
    45             {
    46                 Q.push(next);
    47                 next.x+=rx[i];
    48                 next.y+=ry[i];
    49             }
    50         }
    51     }
    52     return false;
    53 }
    54 int main()
    55 {
    56     int K;
    57     cin>>K;
    58     while(K--)
    59     {
    60         cin>>n>>m;
    61         for(int i=1;i<=n;i++)
    62         {
    63             for(int j=1;j<=m;j++)
    64             {
    65                 cin>>a[i][j];
    66             }
    67         }
    68         cin>>T>>per.y>>per.x>>ey>>ex;//这里注意是先列后行
    69         per.turn=0;
    70         per.dir=-1;
    71         memset(vis,false,sizeof(vis));
    72         if(bfs())cout<<"yes"<<endl;
    73         else cout<<"no"<<endl;
    74     }
    75     return 0;
    76 }
  • 相关阅读:
    android 75 新闻列表页面
    android 74 下载文本
    android 73 下载图片
    android 72 确定取消对话框,单选对话框,多选对话框
    android 71 ArrayAdapter和SimpleAdapter
    android 70 使用ListView把数据显示至屏幕
    maven如何将本地jar安装到本地仓库
    Centos6.7搭建ISCSI存储服务器
    解决maven打包编译出现File encoding has not been set问题
    MySQL 解决 emoji表情 的方法,使用utf8mb4 字符集(4字节 UTF-8 Unicode 编码)
  • 原文地址:https://www.cnblogs.com/Annetree/p/5663782.html
Copyright © 2011-2022 走看看