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 ...
随机推荐
- [Exception JavaWeb 1] - javax.el.PropertyNotFoundException: Property 'id' not found on ..........
好久不写Web应用了,今天碰到这个问题的时候,还一时半会没反应过来.实体类在jsp无法找对应的值. 最后发现是实体bean的属性的开头字母不能与次字母不能大写+小写或小写+大写,最后改成小写+小写就好 ...
- Tomcat 关闭时报错
最近tomcat走普通的关闭方式无法正常关闭,会报一些Error,用的是Tomcat7,据说是Tomcat7在关闭的时候加了一些检查线程泄漏内存泄露的东西 总结起来,在我项目中有这么几个原因会导致关闭 ...
- 【jQuery获取下拉框select、单选框radio、input普通框的值和checkbox选中的个数】
radio单选框:name属性相同 <input type="radio" id="sp_type" name="p_type" va ...
- 使用CXF实现基于Rest方式的WebService
本文介绍使用CXF实现基于Rest方式的WebService(CXF的版本是3.0.0) 一. 前言 Java有三种WebService规范:Jax-WS,Jax-RS,Jaxm 1. Jax-WS( ...
- 执行 maven 命令 报错Unable to add module to the current project as it is not of packaging type 'pom'[转]
今天学习在本地搭建Maven工程时,执行了mvn archetype:generate 命令,报错. Unable to create project from archetype [org.apac ...
- 转:Mosquitto用户认证配置
转自:https://blog.csdn.net/u012377333/article/details/69397124?utm_source=blogxgwz1 前言:基于Mosquitto服务器已 ...
- informix-時間格式的各種用法
以下是我在網路上所收集到的關於informix 時間的sql函數用法,有在使用informix資料庫的人,可以參考看看囉! today,返回現在系統日期 current 返回現在日期含時間,相當於sq ...
- [Jobdu] 题目1408:吃豆机器人
题目描述: 淘宝公司内部有许多新鲜的小玩具,例如淘宝智能机器人.小时候,大家都玩过那个吃豆子的游戏吧,这机器人就是按照这个游戏设计的,它会朝着豆子的方向行走.不过机器人还存在一个bug,他只会朝南和朝 ...
- 连接SQLServer的增删改查方法代码
在Visual C++中用ADO进行数据库编程 1. 生成应用程序框架并初始化OLE/COM库环境 创建一个标准的MFC AppWizard(exe)应用程序CADOConnection,然后在使用A ...
- 点滴积累【C#】---抓取页面中想要的数据
效果: 描述:此功能是抓取外国的一个检测PM2.5的网站.实时读取网站的数据,然后保存到数据库里面.每隔一小时刷新一次. 地址为:http://beijing.usembassy-china.org. ...