码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 1026 Ignatius and the Princess I

时间:2015-02-11 12:51:13      阅读:127      评论:0      收藏:0      [点我收藏+]

标签:acm算法   amp   搜索   printf   c   

Problem Description
The Princess has been abducted by the BEelzebub feng5166, our hero Ignatius has to rescue our pretty Princess. Now he gets into feng5166‘s castle. The castle is a large labyrinth. To make the problem simply, we assume the labyrinth is a N*M two-dimensional array which left-top corner is (0,0) and right-bottom corner is (N-1,M-1). Ignatius enters at (0,0), and the door to feng5166‘s room is at (N-1,M-1), that is our target. There are some monsters in the castle, if Ignatius meet them, he has to kill them. Here is some rules:

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.
 

Input
The input contains several test cases. Each test case starts with a line contains two numbers N and M(2<=N<=100,2<=M<=100) which indicate the size of the labyrinth. Then a N*M two-dimensional array follows, which describe the whole labyrinth. The input is terminated by the end of file. More details in the Sample Input.
 

Output
For each test case, you should output "God please help our poor hero." if Ignatius can‘t reach the target position, or you should output "It takes n seconds to reach the target position, let me show you the way."(n is the minimum seconds), and tell our hero the whole path. Output a line contains "FINISH" after each test case. If there are more than one path, any one is OK in this problem. More details in the Sample Output.
 

Sample Input
5 6 .XX.1. ..X.2. 2...X. ...XX. XXXXX. 5 6 .XX.1. ..X.2. 2...X. ...XX. XXXXX1 5 6 .XX... ..XX1. 2...X. ...XX. XXXXX.
 

Sample Output
It takes 13 seconds to reach the target position, let me show you the way. 1s:(0,0)->(1,0) 2s:(1,0)->(1,1) 3s:(1,1)->(2,1) 4s:(2,1)->(2,2) 5s:(2,2)->(2,3) 6s:(2,3)->(1,3) 7s:(1,3)->(1,4) 8s:FIGHT AT (1,4) 9s:FIGHT AT (1,4) 10s:(1,4)->(1,5) 11s:(1,5)->(2,5) 12s:(2,5)->(3,5) 13s:(3,5)->(4,5) FINISH It takes 14 seconds to reach the target position, let me show you the way. 1s:(0,0)->(1,0) 2s:(1,0)->(1,1) 3s:(1,1)->(2,1) 4s:(2,1)->(2,2) 5s:(2,2)->(2,3) 6s:(2,3)->(1,3) 7s:(1,3)->(1,4) 8s:FIGHT AT (1,4) 9s:FIGHT AT (1,4) 10s:(1,4)->(1,5) 11s:(1,5)->(2,5) 12s:(2,5)->(3,5) 13s:(3,5)->(4,5) 14s:FIGHT AT (4,5) FINISH God please help our poor hero. FINISH
 

Author

Ignatius.L

 

做完这道题,感觉到特别的兴奋。10天了,终于把这道题搞出来了。。刚开始看这道题,一点思路都没有,看网上的代码也根本看不懂。

后来每天都有在这道题上思考。终于,前天学了递归输出路径之后,昨晚又在想这道题,还是没搞出来。今天早上就开始写了。开始慢慢的调试。

终于,经过无数次失败的尝试,加上考虑了各种情况,被我一A了。全程没有看任何他人代码。

越来越感觉,很多东西都是在写了之后调试之后才懂得哪里错了,哪里的情况没考虑。

这道题的解析写的详细点。来纪念我十天的青春!!!!(终于救出了另一个公主)

题意:给你一副地图,问从左上角到右下角最短的时间。

并且输出路径。

‘X’代表墙,‘.’代表能走的路。

数字代表有怪物,并且数字是多少就要打几秒。

OK 上代码。

#include <stdio.h>
#include <string.h>
#include <queue>
#include <stack>
#include <algorithm>
using namespace std;
struct node
{
	int x,y;  //坐标
	int time; //时间
	friend bool operator<(node a,node b)//  优先队列
	{ 
		return a.time>b.time;   // 时间小的优先极高
	}
}
;
int n,m;
int ans;
node pre[105][105];   //   这个数组极为重要,是记录前一步的路径
int fight[105][105];  //   这个数组是后面才加上去的。。
char map[105][105];   //    地图
int vis[105][105]   //   这个数组写在这里,但是貌似没啥用处。
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};  //  方向
bool check(int x1,int y1)
{
	if(x1<0 || y1<0 || x1>=n || y1>=m || map[x1][y1]=='X')  //排除越界的情况
		return 0;  
	return 1;
}
;
int Time;   //   这是计时的用的,第1,2,3,N秒。
void find(node now)   //   这里非常的关键。。用递归输出路径。
{
	int i;
	if(now.x==0 &&now.y==0)
		return;    //    从后面倒回来
	find(pre[now.x][now.y]);   //  递归输出路径。
	if(fight[pre[now.x][now.y].x][pre[now.x][now.y].y])   // 这个也是后来才加进去的,战斗数组。也是随意扔进去一个坐标,就对了。  
	{
		for(i=0;i<fight[pre[now.x][now.y].x][pre[now.x][now.y].y];i++)
			printf("%ds:FIGHT AT (%d,%d)\n",++Time,pre[now.x][now.y].x,pre[now.x][now.y].y);  //用个循环写战斗在第几秒
	}
	printf("%ds:(%d,%d)->(%d,%d)\n",++Time,pre[now.x][now.y].x,pre[now.x][now.y].y,now.x,now.y);//pre是当前的路径,now是下一步的路径,我在find()里面调试了很久很久,弄了各种输出,发现只有这种输出是对的。
	
}
void bfs()
{
	priority_queue<node>q;   //入队。
	node st,ed;
	int i;
	st.x=0;  //  从(0,0)点出发
	st.y=0;  //  从(0,0)点出发
	st.time=0;  //  开始时间为0
	q.push(st);
	while(!q.empty())
	{
		st=q.top();//优先队列的这里是top。不要问为什么,just do it。
		q.pop();
		if(st.x==n-1 &&st.y==m-1)
		{
			ans=st.time;//   要是到达右下角,赋值给ans。(ans一开始为0)
			break;   
		}
		for(i=0;i<4;i++)
		{
			ed.x=st.x+dir[i][0];
			ed.y=st.y+dir[i][1];
			if(!check(ed.x,ed.y))
				continue;     //如果越界或碰到墙,返回继续。
			ed.time=st.time+1;  //时间加一。
			if(map[ed.x][ed.y]>='0' &&map[ed.x][ed.y]<='9')
			{
				ed.time+=map[ed.x][ed.y]-'0'; //加上战斗的时间
                fight[ed.x][ed.y]=map[ed.x][ed.y]-'0';  //后面加上去的一个战斗数组,注意要减掉‘0’才是阿拉伯的数字
			}
			map[ed.x][ed.y]='X';  //这也是一个小技巧吧,变为墙,上面vis标记数组就用不到了,墙是不可走的。
			pre[ed.x][ed.y]=st;  //   这个也是非常重要,记录前一步的路径。
			q.push(ed);
		}
	}
	if(ans)//如果ans不为0,说明成功救出了公主。
	{
		printf("It takes %d seconds to reach the target position, let me show you the way.\n",ans);  //先输出个花了多少秒逃离。
		find(st);  //  然后find(st),就可以轻松输出路径了,但突然感觉不对,因为第二个案例的最后一秒的情况并没有输出来。
	}
	else 
		return;  // 为0直接回到主函数
}
int main()
{
	int i,j,final; //final是用来弄最后一秒的状态的。因为上面的代码输出不了最后一秒的状态,所以后来又加了个final。
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		final=0; //初始化
		for(i=0;i<n;i++)
			scanf("%s",map[i]);
		if(map[n-1][m-1]>='0' &&map[n-1][m-1]<='9')
			final=map[n-1][m-1]-'0';   //这个是最后加进来的,一开始是加到下面的else里面去的,发现还是输出不了最后一秒的情况,想了想,原因是把数字变成‘X’(墙)了
		memset(fight,0,sizeof(fight));
		ans=0;  // 初始化
		Time=0;   // 初始化
		map[0][0]='X';  //  一开始就在这点,变成墙
		bfs();   //强大的bfs
		if(!ans)
			printf("God please help our poor hero.\n");  //如果ans为0说明没救出公主
		else 
		{
			for(i=0;i<final;i++)
				printf("%ds:FIGHT AT (%d,%d)\n",++Time,n-1,m-1); //上面的情况都输完了,考虑最后一步的情况。
		}
		printf("FINISH\n");  //完成。。。
	}
}

//PS:个人感觉自己的代码可读性还是很强的,变量都定义的很清楚,没有乱定义。。


 

HDU 1026 Ignatius and the Princess I

标签:acm算法   amp   搜索   printf   c   

原文地址:http://blog.csdn.net/sky_miange/article/details/43731457

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!