HDU ACM 1180 诡异的楼梯 (优先队列 + 广搜)

http://acm.hdu.edu.cn/showproblem.php?pid=1180

题意:给一幅图,图中有 'S'  'T'  '|'  '-'  '*'  '.'  几种符号,

  '*'表示墙  '.'表示路  'S' 表示 起点.    'T'表示 终点  '|'或者'-' 表示楼梯

  楼梯每过一分钟就会改变一次方向(每走一格一分钟),不能停留在楼梯上且经过楼梯不需要时间.

  求起点到终点最少需要多少时间.

输入:先输入x y 表示x行 y列

  接下来是x行y列的图

输出:输出最少的时间

 

由于楼梯存在两种状态,所以不能直接使用普通的队列(好像是可以的),所以使用优先队列.

一开始的思路是遇到楼梯则判断楼梯状态,若能通过则直接过去,不能通过则再加一步(等待的时间)再过去.

但这样可能会出现下面的问题.

若右下在队头则会出现5步,5步不是最优解.

所以在遇到楼梯且不能通过时,应该原地等一步而不是直接跳过去.(即吧当前队头重新放入队列中.注意是队头而不是加了方向向量的位置.)

 

//View Code
  1 #include <iostream>
  2 #include <queue>
  3 using namespace std;
  4 const int MAX = 20 + 5;
  5 char map[MAX][MAX];
  6 int point[4][2] = {-1,0,0,-1,1,0,0,1};//上 左 下 右
  7 struct Node
  8 {
  9     int x;
 10     int y;
 11     int step;
 12     friend bool operator< (const Node &a,const Node &b)
 13     {
 14         return a.step > b.step;
 15     }
 16 };
 17 int judge(Node a_k,int i_k)
 18 {
 19     if(map[a_k.x][a_k.y] == '|')
 20     {
 21         if(i_k%2 == 0)//上下走
 22         {
 23             if(a_k.step % 2 == 0)//
 24             {
 25                 return 0;
 26             }
 27             else//不变
 28             {
 29                 return 1;
 30             }
 31         }
 32         else//左右走
 33         {
 34             if(a_k.step % 2 == 0)//
 35             {
 36                 return 1;
 37             }
 38             else//不变
 39             {
 40                 return 0;
 41             }
 42         }
 43     }
 44     else
 45     {
 46         if(map[a_k.x][a_k.y] == '-')
 47         {
 48             if(i_k%2 == 0)//上下走
 49             {
 50                 if(a_k.step%2 == 0)//
 51                 {
 52                     return 1;
 53                 }
 54                 else//不变
 55                 {
 56                     return 0;
 57                 }
 58             }
 59             else//左右走
 60             {
 61                 if(a_k.step%2 == 0)//
 62                 {
 63                     return 0;
 64                 }
 65                 else//不变
 66                 {
 67                     return 1;
 68                 }
 69             }
 70         }
 71     }
 72 }
 73 int x,y;
 74 int BFS(Node a,Node b)
 75 {
 76     priority_queue <Node> q;
 77     a.step = 0;
 78     q.push(a);
 79     map[a.x][a.y] = '*';
 80     while(!q.empty())
 81     {
 82         Node mid;
 83         mid = q.top ();
 84         if(mid.x== b.x && mid.y == b.y)
 85         {
 86             cout<<mid.step<<endl;
 87             return 0;
 88         }
 89         mid.step++;
 90         q.pop();
 91         int i;
 92         for(i=0;i<4;i++)
 93         {
 94             a.x = mid.x + point[i][0];
 95             a.y = mid.y + point[i][1];
 96             a.step = mid.step;
 97             if(a.x <=x && a.y <=y && a.x >= 1 && a.y >= 1 && map[a.x][a.y] != '*')
 98             {
 99                 if(map[a.x][a.y] == '.' || map[a.x][a.y] == 'T')
100                 {
101                     map[a.x][a.y] = '*';
102                     q.push(a);
103                 }
104                 else
105                 {
106                     if(map[a.x][a.y] == '|' || map[a.x][a.y] == '-')
107                     {
108                         if(judge(a,i))
109                         {
110                             a.x = a.x + point[i][0];
111                             a.y = a.y + point[i][1];
112                             if( map[a.x][a.y] != '*')
113                             {
114                                 if(map[a.x][a.y] == '.' || map[a.x][a.y] == 'T')
115                                 {
116                                     map[a.x][a.y] = '*';
117                                     q.push (a);
118                                 }
119                             }
120                         }
121                         else
122                         {
123                             q.push (mid);//小心不要写成q.push(a)
124                         }
125                     }
126                 }
127             }
128         }
129     }
130 }
131 int main()
132 {
133     while(cin>>x>>y)
134     {
135         memset(map,0,sizeof(map));
136         int i,j;
137         Node s,e;
138         for(i=1;i<=x;i++)
139         {
140             for(j=1;j<=y;j++)
141             {
142                 cin>>map[i][j];
143                 if(map[i][j] == 'S')
144                 {
145                     s.x = i;
146                     s.y = j;
147                 }
148                 if(map[i][j] == 'T')
149                 {
150                     e.x = i;
151                     e.y = j;
152                 }
153             }
154         }
155         BFS(s,e);
156     }
157     return 0;
158 }

 

转载于:https://www.cnblogs.com/zxotl/archive/2012/09/02/2667495.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值