hdu 1026:Ignatius and the Princess I(优先队列 + bfs广搜。ps:广搜AC,深搜超时,求助攻!)
Ignatius and the Princess I
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 10541 Accepted Submission(s): 3205
Special Judge
1.Ignatius can only move in four directions(up, down, left, right), one step per second. A step is defined as follow: if current position is (x,y), after a step, Ignatius can only stand on (x-1,y), (x+1,y), (x,y-1) or (x,y+1).
2.The array is marked with some characters and numbers. We define them like this:
. : The place where Ignatius can walk on.
X : The place is a trap, Ignatius should not walk on it.
n : Here is a monster with n HP(1<=n<=9), if Ignatius walk on it, it takes him n seconds to kill the monster.
Your task is to give out the path which costs minimum seconds for Ignatius to reach target position. You may assume that the start position and the target position will never be a trap, and there will never be a monster at the start position.
.XX..
..X..
...X.
...XX.
XXXXX. .XX..
..X..
...X.
...XX.
XXXXX1 .XX...
..XX1.
...X.
...XX.
XXXXX.
It takes seconds to reach the target position, let me show you the way.
1s:(,)->(,)
2s:(,)->(,)
3s:(,)->(,)
4s:(,)->(,)
5s:(,)->(,)
6s:(,)->(,)
7s:(,)->(,)
8s:FIGHT AT (,)
9s:FIGHT AT (,)
10s:(,)->(,)
11s:(,)->(,)
12s:(,)->(,)
13s:(,)->(,)
FINISH
It takes seconds to reach the target position, let me show you the way.
1s:(,)->(,)
2s:(,)->(,)
3s:(,)->(,)
4s:(,)->(,)
5s:(,)->(,)
6s:(,)->(,)
7s:(,)->(,)
8s:FIGHT AT (,)
9s:FIGHT AT (,)
10s:(,)->(,)
11s:(,)->(,)
12s:(,)->(,)
13s:(,)->(,)
14s:FIGHT AT (,)
FINISH
God please help our poor hero.
FINISH
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
struct Way{
int x;
int y;
bool ism;
}way[]; //存储每一秒走到的位置,及有没有怪物
char maze[][];
bool isv[][];
int dx[]={,,,-};
int dy[]={,,-,};
int curx,cury;
int endx,endy;
int N,M;
int _min;
int dfs(int curx,int cury,int s) //当前的位置以及走到这个位置用的时间(秒)和方向
{
int n=;
if(curx==N- && cury==M-){
//到达终点
_min=s;
if(''<=maze[curx][cury] && maze[curx][cury]<=''){
//如果当前位置有怪物
int t; //怪物的HP
t=maze[curx][cury]-'';
for(int i=;i<=t;i++){
way[s-i].x=curx;
way[s-i].y=cury;
way[s-i].ism=true;
}
}
else{
//当前位置没有怪物
way[s].x=curx;
way[s].y=cury;
way[s].ism=false;
}
return s;
}
//没有走到终点的时候
for(int i=;i<;i++){
int nx = curx+dx[i];
int ny = cury+dy[i];
if(<=nx && nx<=N- && <=ny && ny<=M- //如果没有越界
&& maze[nx][ny]!='X' //下一步没有陷阱
&& !isv[nx][ny] //下一步没走过
){
int t; //有怪物的话存储怪物的HP,否则为1
if(''<=maze[nx][ny] && maze[nx][ny]<=''){
t=int(maze[nx][ny]-'')+;
}
else{
t=;
}
if(s+t>=_min) continue; //再次剪枝
isv[nx][ny]=true;
int tt;
if( tt=dfs(nx,ny,s+t) ){
//找到最短路
n=tt;
way[s].x=curx;
way[s].y=cury;
way[s].ism=false;
if(''<=maze[curx][cury] && maze[curx][cury]<=''){
//如果当前位置有怪物
int t; //怪物的HP
t=maze[curx][cury]-'';
for(int i=;i<=t;i++){
way[s-i].x=curx;
way[s-i].y=cury;
way[s-i].ism=true;
}
}
}
isv[nx][ny]=false;
}
}
return n;
}
int main()
{
while(scanf("%d%d",&N,&M)!=EOF){ //开始一个新的地图
getchar();
memset(isv,,sizeof(isv)); //初始化
_min=;
curx=,cury=; //初始化开始、终点位置
endx=N-,endy=M-;
for(int i=;i<N;i++){
for(int j=;j<M;j++){
scanf("%c",&maze[i][j]);
}
getchar();
}
int n; //如果能走到终点的话,接收最短步数
isv[][]=true;
n=dfs(curx,cury,);
if(n){
//能走
printf("It takes %d seconds to reach the target position, let me show you the way.\n",n);
for(int i=;i<n;i++){
if(way[i].ism){
//如果有怪物
printf("%ds:FIGHT AT (%d,%d)\n",i+,way[i].x,way[i].y);
}
else {
printf("%ds:(%d,%d)->(%d,%d)\n",i+,way[i].x,way[i].y,way[i+].x,way[i+].y);
}
}
}
else{
//走不到终点
printf("God please help our poor hero.\n");
}
printf("FINISH\n");
}
return ;
}
2014/1/16 22:51:00
#include <iostream>
#include <string.h>
#include <queue>
using namespace std;
char a[][]; //记录地图
char b[][]; //备用地图,用以修改
int isv[][]; //记录访问过没有
int way[][]; //记录路径
int dx[] = {,,,-};
int dy[] = {,,-,};
int N,M;
struct NODE{
int x;
int y;
int step;
};
bool judge(int x,int y)
{
if( x< || y< || x>N || y>M ) //出界
return ;
if( isv[x][y] ) //走过
return ;
if( a[x][y]=='X' ) //遇到墙
return ;
return ;
}
int bfs(int x,int y) //返回到达终点的时间(包括在终点停留的时间)
{
for(int i=;i<=N;i++)
for(int j=;j<=M;j++)
b[i][j] = a[i][j];
queue <NODE> q;
NODE cur,next;
cur.x = x;
cur.y = y;
cur.step = ;
q.push(cur); //第一个节点入队
while(!q.empty()){
cur = q.front();
q.pop(); //队首出队
if( cur.x==N && cur.y==M ){
int num = ;
if(''<=b[cur.x][cur.y] && b[cur.x][cur.y]<='')
num = b[cur.x][cur.y] - '';
return cur.step + num;
}
if(''<=b[cur.x][cur.y] && b[cur.x][cur.y]<=''){ //遇到怪物,step+1,位置不变,入队
next.x = cur.x;
next.y = cur.y;
next.step = cur.step + ;
q.push(next);
if(b[cur.x][cur.y]=='')
b[cur.x][cur.y] = '.';
b[cur.x][cur.y]--;
continue;
}
for(int i=;i<;i++){
int nx = cur.x + dx[i];
int ny = cur.y + dy[i];
if(judge(nx,ny)) //判定
continue;
//可以走
next.x = nx;
next.y = ny;
way[nx][ny] = i; //记录路径
isv[nx][ny] = true; //记录访问过
next.step = cur.step + ;
q.push(next);
}
}
return ;
}
int main()
{
while(cin>>N>>M){
for(int i=;i<=N;i++)
for(int j=;j<=M;j++)
cin>>a[i][j];
memset(isv,,sizeof(isv));
isv[][] = true;
int step = bfs(,);
if(step){ //到达终点
NODE way_node[];
int cx=N,cy=M;
for(int i=step;i>=;i--){ //根据way[][]还原路径
way_node[i].x = cx;
way_node[i].y = cy;
int num=;
if(''<=a[cx][cy] && a[cx][cy]<='') //如果该位置有怪物
num = a[cx][cy] - '';
for(int j=num;j>=;j--){
way_node[i-j].x = cx;
way_node[i-j].y = cy;
}
if(num){
i-=num;
}
switch(way[cx][cy]){ //没有怪物则继续还原路径
case :cy--;break;
case :cx--;break;
case :cy++;break;
case :cx++;break;
default:break;
}
}
//输出结果
cout<<"It takes "<<step<<" seconds to reach the target position, let me show you the way."<<endl;
for(int i=;i<=step;i++){
cout<<i<<"s:("<<way_node[i-].x-<<','<<way_node[i-].y-<<")->("<<way_node[i].x-<<','<<way_node[i].y-<<')'<<endl;
cx = way_node[i].x;
cy = way_node[i].y;
if(''<=a[cx][cy] && a[cx][cy]<=''){
int num = a[cx][cy] - '';
for(int j=;j<=num;j++)
cout<<i+j<<"s:FIGHT AT ("<<way_node[i].x-<<','<<way_node[i].y-<<')'<<endl;
i += num;
}
}
cout<<"FINISH"<<endl;
}
else{ //没有到达终点
cout<<"God please help our poor hero."<<endl;
cout<<"FINISH"<<endl;
}
}
return ;
}
2014-01-18 16:50:53
受同学启发,用“优先队列”又写了一遍,顺便学习了一下优先队列的使用。
思路和上面是基本相同的,只不过遇到怪物时的处理用优先队列简化了许多,优先队列不会用的筒靴可以参考下面的链接:
另外给出一位同样用优先队列实现的博客链接,不过人家是0MS AC,我是31MS AC,有差距啊!
下面是我用优先队列做的代码:
#include <iostream>
#include <string.h>
#include <queue>
using namespace std;
char a[][];
char isv[][]; //记录访问过没有
int dir[][]; //记录每一个节点的来路方向,即整个地图遍历的顺序
int dx[] = {,,,-};
int dy[] = {,,-,};
int N,M;
struct NODE{
int x;
int y;
int step;
friend bool operator < (NODE n1,NODE n2) //自定义优先级。在优先队列中,优先级高的元素先出队列。
{
return n1.step > n2.step; //通过题意可知 step 小的优先级高,需要先出队。
}
};
bool judge(int x,int y)
{
if( x< || y< || x>N || y>M )
return ;
if( isv[x][y] )
return ;
if( a[x][y]=='X' )
return ;
return ;
}
int bfs(int x,int y) //返回从(x,y)开始广搜,到右下角的最短步数,如果无法到达右下角,返回0
{
priority_queue <NODE> q; //定义一个优先队列
NODE cur,next;
cur.x = x;
cur.y = y;
cur.step = ;
q.push(cur); //第一个元素入队
while(!q.empty()){
cur = q.top(); //队首出队,注意不是front()
q.pop();
if(cur.x==N && cur.y==M){ //到终点
return cur.step;
}
for(int i=;i<;i++){
int nx = cur.x + dx[i];
int ny = cur.y + dy[i];
if( judge(nx,ny) ) //判定
continue;
//可以走
next.x = nx;
next.y = ny;
isv[nx][ny] = true;
dir[nx][ny] = i;
if( ''<=a[nx][ny] && a[nx][ny]<='' ){ //这一步有怪物
int hp = a[nx][ny] - '';
next.step = cur.step + hp + ;
}
else //这一步没有怪物
next.step = cur.step + ;
q.push(next);
}
}
return ;
}
int main()
{
while(cin>>N>>M){
for(int i=;i<=N;i++)
for(int j=;j<=M;j++)
cin>>a[i][j];
memset(isv,,sizeof(isv));
isv[][] = true;
int step = bfs(,);
if(step){ //step有值,能够到达终点
//还原路径
NODE way[];
int cx=N,cy=M;
for(int i=step;i>=;i--){
way[i].x = cx;
way[i].y = cy;
if(''<=a[cx][cy] && a[cx][cy]<=''){ //当前位置有怪物
int hp = a[cx][cy] - '';
for(int j=;j<=hp;j++){
way[i-j].x = cx;
way[i-j].y = cy;
}
i -= hp;
}
switch(dir[cx][cy]){
case :cy--;break;
case :cx--;break;
case :cy++;break;
case :cx++;break;
default:break;
}
}
//输出结果
cout<<"It takes "<<step<<" seconds to reach the target position, let me show you the way."<<endl;
for(int i = ;i<=step;i++){
cout<<i<<"s:("<<way[i-].x-<<','<<way[i-].y-<<")->("<<way[i].x-<<','<<way[i].y-<<')'<<endl;
if( ''<=a[way[i].x][way[i].y] && a[way[i].x][way[i].y]<='' ){ //如果有怪物
int hp = a[way[i].x][way[i].y] - '';
for(int j=;j<=hp;j++)
cout<<i+j<<"s:FIGHT AT ("<<way[i+j].x-<<','<<way[i+j].y-<<')'<<endl;
i+=hp;
}
}
}
else{ //step为0,说明不能到达终点
cout<<"God please help our poor hero."<<endl;
}
cout<<"FINISH"<<endl;
}
return ;
}
Freecode : www.cnblogs.com/yym2013
hdu 1026:Ignatius and the Princess I(优先队列 + bfs广搜。ps:广搜AC,深搜超时,求助攻!)的更多相关文章
- hdu 1026 Ignatius and the Princess I(优先队列+bfs+记录路径)
以前写的题了,现在想整理一下,就挂出来了. 题意比较明确,给一张n*m的地图,从左上角(0, 0)走到右下角(n-1, m-1). 'X'为墙,'.'为路,数字为怪物.墙不能走,路花1s经过,怪物需要 ...
- HDU 1026 Ignatius and the Princess I(BFS+优先队列)
Ignatius and the Princess I Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d &am ...
- hdu 1026 Ignatius and the Princess I(bfs)
Ignatius and the Princess I Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (J ...
- HDU 1026 Ignatius and the Princess I (BFS)
题目链接 题意 : 从(0,0)点走到(N-1,M-1)点,问最少时间. 思路 : BFS..... #include <stdio.h> #include <string.h> ...
- hdu 1026 Ignatius and the Princess I(BFS+优先队列)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1026 Ignatius and the Princess I Time Limit: 2000/100 ...
- hdu 1026 Ignatius and the Princess I
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1026 Ignatius and the Princess I Description The Prin ...
- hdu 1026 Ignatius and the Princess I【优先队列+BFS】
链接: http://acm.hdu.edu.cn/showproblem.php?pid=1026 http://acm.hust.edu.cn/vjudge/contest/view.action ...
- hdu 1026 Ignatius and the Princess I (bfs+记录路径)(priority_queue)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1026 Problem Description The Princess has been abducted ...
- hdu 1026 Ignatius and the Princess I 搜索,输出路径
Ignatius and the Princess I Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (J ...
随机推荐
- 〖C++〗string2int把字符串转换成int的函数
#include <stdio.h> #include <stdlib.h> #include <string.h> int string2int(char *ar ...
- 微信小程序列表加载更多
概述 基于小程序开发的列表加载更多例子. 详细 代码下载:http://www.demodashi.com/demo/13632.html 一.前言 基于小程序开发的列表加载更多例子. 二.运行效果 ...
- spring mvc 返回json的配置
转载自:http://my.oschina.net/haopeng/blog/324934 springMVC-servlet.xml 配置 1 2 3 4 5 6 7 8 9 10 11 12 13 ...
- getAttribure()和getParameter()的区别
1.getAttribute是取得jsp中 用setAttribute设定的attribute 2.parameter得到的是string:attribute得到的是object 3.request. ...
- Django的ORM中如何判断查询结果是否为空,判断django中的orm为空
result= Booking.objects.filter() #方法一 .exists() if result.exists(): print "QuerySet has Data&qu ...
- spring in action小结2
1 @Component注解声明的类都会创建为bean,并且bean的id为首字母小写的类名. 2 解决bean自动装配奇异性问题,可以使用@Qualifier("name")限定 ...
- node.js 操作excel 表格与XML文件常用的npm
在日常工作中会经常用到把一些excel表格文件转化为json,xml,js等格式的文件,下面就是我在日常中用到的这些npm. 1.node-xlsx: node-xlsx可以把excel文件转化为上面 ...
- Android Studio 使用感受 错误解决
刚到公司不久,公司叫我用Android studio软件,曾经一直在用的是eclipse ADT.突然接触到的新名词让我有点适应只是来. 好吧,既然是公司要求,肯定有它的道理.就从网上下载了它的安装包 ...
- html-blogsdemo
博客标题小样,代码预览是有动态效果的,但在博客园发布就没动画了,知道的大神麻烦告知下,谢谢. code <!DOCTYPE html> <html lang="en&quo ...
- C++之把流对象当做函数参数传递
一.编译不通过的代码: /******************************************************************************* * File ...