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++设计模式实现--职责链(Chain of Responsibility)模式
一. 概述 职责链模式: 使多个对象都有机会处理请求.从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. 二. 举个样例 员工要求加薪 ...
- SyntaxError: Non-ASCII character '\xe5' in file index.py on line 6, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
python入门,hhh 在慕课网上学习python入门,编写汉诺塔的递归调用时,代码正确.但是加上注释后编译不通过 报如下错误: SyntaxError: Non-ASCII character , ...
- ios开发-Object-C可变参数函数
简介 一个可变参数函数是指一个函数拥有不定的参数,即为一个函数可接收多个参数.有时我们会遇到一些算术问题需要用到,比如是计算传入参数的总和,字符串的连接或是其它操作过程,我们在 OC 里也经常使用,最 ...
- Pytorch中的norm跟Numpy中的norm对比
- mysql优化三
1. 为查询缓存优化你的查询 大多数的MySQL服务器都开启了查询缓存.这是提高性最有效的方法之一,而且这是被MySQL的数据库引擎处理的.当有很多相同的查询被执行了多次的时候,这些查询结果会被放到一 ...
- Provisional headers are shown(一)
谷歌浏览器调试的时候,这个警告经常出现.但是每次产生的原因可能都是不一样的. 这篇文档记录我遇到的其中一次. 现象:一个并发的错误信息: CAUTION:request is not finished ...
- 使用maven开发OSGI样例
一:创建maven项目,在pom.xml里面增加例如以下依赖 <dependency> <groupId>org.osgi</groupId> <artifa ...
- IntelliJ IDEA 学习(一):IntelliJ IDEA15 破解方法(已验证)
新的破解方法: 1.进到文件夹中:C:\Windows\System32\drivers\etc ,找到hosts文件,用记事本编辑 2.如果没有找到hosts文件,可在查看设置中勾选“显示隐藏的项目 ...
- effactive java读书小结1
java程序设计的原则 1 清晰性和原则性最为重要:模块:任何可重用的软件组件,从单个方法到复杂系统都可以是一个模块.代码应该被重用而不是被拷贝.模块之间的依赖性应该降到最小:错误应尽早检查出来,最好 ...
- Redis(七):Jedis简介和集群
Jedis简介 1.Jedis 是Redis 客户端工具jar2.使用非集群版示例代码 Jedis jedis = new Jedis("192.168.139.132", 637 ...