看题传送门:

ZOJ http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1649

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

题目大意初始位置在r,要求到达a的地点,地图上"."通过需要1s,“x"代表守卫,通过耗时2s,“#”不能走。

BFS的应用。

BFS求最短路径的原理是每一次向外扩张一格,(就像树的层次遍历一样),生成的BFS树把同一步数放于同一层,故能保证最优解。

这题变形之处在于,迷宫上有守卫,打到守卫需要1s,才能进入守卫所在的格子。

故不能简单的BFS。

1.

我想到的方法是:

用一个数组记录当前到达的最小步数,如果走过一个格子,下一次走过的时间比较短,那么入队列,更新数组。否则跳过。

2.

看了别人的方法还有:

先在进入守卫所在的地方然后干掉守卫。

如果当前的格子是x则把步数+1,还有把x改为.   并重新入队列。

剩下的就是简单的BFS。

3.

优先队列。。。。Orz大牛。

把队列里面的各个点的步数从小到大,先到达目标的一定是最优的。。。。Orz

方法一:BFS+剪枝。

#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int MAXN=200+10;
const int INF=999999;
char maze[MAXN][MAXN];
int vis[MAXN][MAXN];
const int dx[]={1,-1,0,0};
const int dy[]={0,0,1,-1};
int N,M;
struct site
{
int x,y;
int step;
site(int i,int j,int s){x=i;y=j;step=s;}
site(){}
}start,en; queue<site> q;
void bfs()
{ q.push(start);
int i;
while(!q.empty())
{
site cur=q.front();
//等下试试temp,而不是q.push(site(nx,ny));
q.pop();
for(i=0;i<4;i++)
{
int nx=cur.x+dx[i];
int ny=cur.y+dy[i];
int ns=cur.step; if( nx>=0 && ny >=0 && nx < N && ny < M && maze[nx][ny]!='#' )
{ if(maze[nx][ny]=='a' && ns+1 < en.step )
{
en.step=ns+1;
continue;
} if(maze[nx][ny]=='.'&& ns + 1 < vis[nx][ny] ) //剪枝
{
vis[nx][ny]=ns+1;
q.push(site(nx,ny,ns+1));
} if (maze[nx][ny]=='x' && ns + 2 < vis[nx][ny] )
{
vis[nx][ny]=ns+2;
q.push(site(nx,ny,ns+2));
}
}
}
} } int main()
{
while(scanf("%d%d",&N,&M)!=EOF)
{
while(!q.empty())
q.pop(); getchar();
int i,j;
for(i=0;i<N;i++)
{
for(j=0;j<M;j++)
{
scanf("%c",&maze[i][j]);
if(maze[i][j]=='r')
{
start.x=i;
start.y=j;
start.step=0;
}
else if(maze[i][j]=='a')
{
en.x=i;
en.y=j;
en.step=INF;
}
vis[i][j]=INF;
}
getchar();
} bfs(); if(en.step==INF)
printf("Poor ANGEL has to stay in the prison all his life.\n");
else
printf("%d\n",en.step);
}
}

方法二:先干掉守卫

#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int MAXN=200+10;
const int INF=999999;
char maze[MAXN][MAXN];
bool vis[MAXN][MAXN];
const int dx[]={1,-1,0,0};
const int dy[]={0,0,1,-1};
int N,M;
struct site
{
int x,y;
int step;
site(int i,int j,int s){x=i;y=j;step=s;}
site(){}
}start,en; queue<site> q;
void bfs()
{
memset(vis,0,sizeof(vis));
q.push(start);
int i;
while(!q.empty())
{
site cur=q.front();
q.pop(); if(maze[cur.x][cur.y]=='x')
{
maze[cur.x][cur.y]='.';
cur.step++;
q.push(cur);
continue;
} for(i=0;i<4;i++)
{
int nx=cur.x+dx[i];
int ny=cur.y+dy[i];
int ns=cur.step; if( nx>=0 && ny >=0 && nx < N && ny < M && maze[nx][ny]!='#' &&!vis[nx][ny])
{ if(maze[nx][ny]=='a' )
{
en.step=ns+1;
return;
}
//此时无需判断是否为x或者.,因为我们是先干掉守卫然后在进入守卫所在的地方。
q.push(site(nx,ny,ns+1)); vis[nx][ny]=true;
}
}
}
} int main()
{
while(scanf("%d%d",&N,&M)!=EOF)
{
while(!q.empty())
q.pop(); getchar();
int i,j;
for(i=0;i<N;i++)
{
for(j=0;j<M;j++)
{
scanf("%c",&maze[i][j]);
if(maze[i][j]=='r')
{
start.x=i;
start.y=j;
start.step=0;
}
else if(maze[i][j]=='a')
{
en.x=i;
en.y=j;
en.step=INF;
}
}
getchar();
} bfs(); if(en.step==INF)
printf("Poor ANGEL has to stay in the prison all his life.\n");
else
printf("%d\n",en.step);
}
}

方法三: 优先队列

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int MAXN=200+10;
const int INF=0x3ffffff;
char map[MAXN][MAXN];
bool vis[MAXN][MAXN];
const int dx[]={1,-1,0,0};
const int dy[]={0,0,1,-1}; struct node
{
int step,x,y;
node(){}
node(int x,int y,int step): x(x),y(y),step(step){}
bool operator < (const node&a)const{
return step>a.step;
}
}s,e; void bfs()
{
memset(vis,0,sizeof(vis));
priority_queue<node> q;
q.push(s);
vis[s.x][s.y]=true;
while(!q.empty())
{
node cur=q.top();
q.pop();
for(int i=0;i<4;i++)
{
int nx=cur.x+dx[i],ny=cur.y+dy[i];
if(map[nx][ny]=='a')
{
e.step=cur.step+1;
return;
}
if(map[nx][ny]!='#'&&!vis[nx][ny])
{
if(map[nx][ny]=='x')
{
q.push(node(nx,ny,cur.step+2));
map[nx][ny]='.';
vis[nx][ny]=true;
}
else
{
q.push(node(nx,ny,cur.step+1));
vis[nx][ny]=true;
}
}
}
}
} int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
for(int i=1;i<=n;i++)
{
scanf("%s",map[i]+1);
for(int j=1;j<=m;j++)
{
if(map[i][j]=='a')
{
e.x=i;e.y=j;e.step=INF;
}
if(map[i][j]=='r')
{
s.x=i;s.y=j;s.step=0;
}
}
} for(int i=0;i<=m+1;i++)
map[0][i]=map[n+1][i]='#';
for(int i=0;i<=n+1;i++)
map[i][0]=map[i][m+1]='#'; /* for(int i=0;i<=n+1;i++)
{
for(int j=0;j<=m+1;j++)
printf("%c",map[i][j]);
printf("\n");
}*/
bfs();
if(e.step==INF)
puts("Poor ANGEL has to stay in the prison all his life.");
else
printf("%d\n",e.step);
}
return 0;
}

ZOJ-1649 Rescue BFS (HDU 1242)的更多相关文章

  1. zoj 1649 Rescue (BFS)(转载)

    又是类似骑士拯救公主,不过这个是朋友拯救天使的故事... 不同的是,天使有多个朋友,而骑士一般单枪匹马比较帅~ 求到达天使的最短时间,杀死一个护卫1 units time , 走一个格子 1 unit ...

  2. ZOJ 1649 Rescue(有敌人迷宫BFS)

    题意 求迷宫中从a的位置到r的位置须要的最少时间  经过'.'方格须要1s  经过'x'方格须要两秒  '#'表示墙 因为有1s和2s两种情况  须要在基础迷宫bfs上加些推断 令到达每一个点的时间初 ...

  3. zoj 1649 Rescue

    BFS..第一次使用C++ STL的队列来写广搜. #include<stdio.h> #include<string.h> #include<math.h> #i ...

  4. hdu 1242 Rescue

    题目链接:hdu 1242 这题也是迷宫类搜索,题意说的是 'a' 表示被拯救的人,'r' 表示搜救者(注意可能有多个),'.' 表示道路(耗费一单位时间通过),'#' 表示墙壁,'x' 代表警卫(耗 ...

  5. BFS zoj 1649

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1649 //hnldyhy(303882171) 11:12:46 // z ...

  6. POJ 1511 Invitation Cards / UVA 721 Invitation Cards / SPOJ Invitation / UVAlive Invitation Cards / SCU 1132 Invitation Cards / ZOJ 2008 Invitation Cards / HDU 1535 (图论,最短路径)

    POJ 1511 Invitation Cards / UVA 721 Invitation Cards / SPOJ Invitation / UVAlive Invitation Cards / ...

  7. HDU 1242 Rescue(BFS),ZOJ 1649

    题目链接 ZOJ链接 Problem Description Angel was caught by the MOLIGPY! He was put in prison by Moligpy. The ...

  8. hdu - 1242 Rescue && hdu - 2425 Hiking Trip (优先队列+bfs)

    http://acm.hdu.edu.cn/showproblem.php?pid=1242 感觉题目没有表述清楚,angel的朋友应该不一定只有一个,那么正解就是a去搜索r,再用普通的bfs就能过了 ...

  9. hdu 1242 Rescue(bfs)

    此刻再看优先队列,不像刚接触时的那般迷茫!这也许就是集训的成果吧! 加油!!!优先队列必须要搞定的! 这道题意很简单!自己定义优先级别! +++++++++++++++++++++++++++++++ ...

随机推荐

  1. 欧拉回路&欧拉路径学习笔记

    基础性质(用来判定): 1.无向图欧拉回路没有奇数点 (有向图所有点入度等于出度) 2.无向图欧拉路径只有两个奇数点 (有向图有一个顶点入度比出度大1,有一个顶点出度比入度大1,其他的全相等) 3.图 ...

  2. JDBC连接池C3P0

    连接池 1)传统方式找DriverManager要连接.数目是有限的. 2)传统方式的close().并没有将Connection重用.仅仅是切断应用程序和数据库的桥梁,即无发送到SQL命令到数据库端 ...

  3. Tomcat之——配置项目有虚拟路径

    转载请注明出处:http://blog.csdn.net/l1028386804/article/details/47024863 非常easy,在Tomcat的Server.xml文件里的Host节 ...

  4. JMS基础知识

    JMS规范: jms的基本构件:  连接工厂(connectionFactory):客户用来创建连接的对象.比如:activeMQ提供的ActiveMQConnectionFactory. 连接(co ...

  5. hdu 1233 还是畅通project (克鲁斯卡尔裸题)

    还是畅通project                                              Time Limit: 4000/2000 MS (Java/Others)    M ...

  6. actionbar-去掉背景的阴影

    今天发现一个问题,就是actionbar跟界面的交界处,会有一个阴影,通过调查发现,这个阴影是actionbar的.然后通过在网上找资料,完美解决了问题.解决方法如下 1.在这个actionbar所在 ...

  7. C#异步编程的实现方式(4)——Task任务

    最基本的是知道怎么启动一个Task. 1.Task类构造函数 使用Task类的构造函数.实例化Task对象时,任务不会立即运行,而是指定Created状态.接着调用Task类的Start()方法来启动 ...

  8. nginx安装部署+增加媒体播放模块

    nginx安装很简单,但是有的时候是已经安装的nginx ,升级增加nginx 模块功能. 最近公司要nginx增加一个可以播放 MP4的模块,安装还算顺利,不说废话上命令. 1 安装依赖 yum i ...

  9. 反序列化xml到treeview

    private void Form1_Load(object sender, EventArgs e) { string xmlPath = System.Environment.CurrentDir ...

  10. [D3] Draw a basic US d3-geo map

    Install: npm install --save d3 d3-geo topojson Code: import React, {Component} from 'react'; import ...