题意:给你一张n*m的图,其中:

“ . ”代表可以走的空地

“ # ”代表不能走的墙

“ * ”代表传送门,当你从一个非传送们走到一个传送门的时候,你只能选择传送到除这个传送们外其他的传送门,如过没有其他传送们可以走,你就会死掉;当你到达传送门是由其他传送们传送到的,你既可以选择继续传送,也可以选择走到该传送们的相邻位置。

“ P ”代表初始位置

“ D ”代表目标位置

从出发位置开始,每次只能走到它相邻的位置,问你走到目标位置要走的最少步数,不能走到输出“ -1 ”.

思路:因为要找的是最少步数,所有我用的是bfs,对于所有的传送门,我们要分两种时间来处理,一种是到达该传送们的时间的最短时间,用vt数组保存,一种是当该传送们可以向四周走的时候的时间,用use数组保存,,我们先将他们初始化为0(代表未到或者不能往四周走),每次到达传送门的时候,如果它的vt时间非零,那我们用它来更新其他所有use为零的传送门(因为当从一个传送们到另一个传送门时,我们可以选择往四周走或者继续传送)(代表该传送门可以往四周走),否则它的use时间来更新(因为它没有其他的非传送门位置可以到达它,所以只能用use时间来更新其他use为零的点)(我们是用bfs,所以我们一定是按照时间的非递减来更新每一个点的,每个点)(每一个传送门只要能往四周走的时候我们就不用更新他的use值了,差不多第一次到达传送门时(假设有k个传送门),我们用到达它的vt时间来更新其他k-1个传送门的use时间,然后用第二个到达的传送门更新第一个传送门的use值就可以了,以后都不要再继续传送了,因为每个传送门都可以向四周走了,再传送时间肯定不是最短的

#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
struct st{
int x,y;
};
char s[210][210];//存地图
int vt[210][210];//到达时间
int x1[4]={0,1,0,-1};
int y1[4]={1,0,-1,0};
int use[210][210]; //存每个传送门可以向四周走的时间
vector<st> v;//存传送门的位置
queue<st> q;
st a1,b1,c;
int n,m,lg;
bool check(st a){//检验是否能走
if(a.x>0&&a.x<=n&&a.y<=m&&a.y>0&&s[a.x][a.y]!='#'&&!vt[a.x][a.y])
return true;
return false;
}
int bfs(){
int i,j;
while(!q.empty())
q.pop();
q.push(a1);
vt[a1.x][a1.y]=1;//标记初始位置
st a,b;\
lg=1;
while(!q.empty()){
a=q.front();
q.pop();
int tm=vt[a.x][a.y];//该点的到达时间
// printf("%d %d %d %d\n",a.x,a.y,tm,use[a.x][a.y]); if(s[a.x][a.y]=='*'){//当是传送门的时候
if(lg&&v.size()>1){//如果有不止一个传送门并且还有传送门不能向四周走
c.x=a.x;
c.y=a.y;
lg=0;
for(j=0;j<v.size();j++){//继续传送到其他没到过的传送门
if((v[j].x!=a.x)||(v[j].y!=a.y)){//不能传自己
if(!use[v[j].x][v[j].y]){//如果它没到过
if(!vt[a.x][a.y])//如果更新它的时候它还没有被非传送门的位置更新
use[v[j].x][v[j].y]=use[a.x][a.y]+1;
else
use[v[j].x][v[j].y]=tm+1;
lg=1;
q.push(v[j]);
} }
}
}
if(use[a.x][a.y]){//向四周走
for(i=0;i<4;i++){
b.x=a.x+x1[i];
b.y=a.y+y1[i];
if(check(b)&&s[b.x][b.y]!='*'){//不能走传送门
vt[b.x][b.y]=use[a.x][a.y]+1;
q.push(b);
}
}
}
}
else{
for(i=0;i<4;i++){//如果该点是非传送门,正常先四周走
b.x=a.x+x1[i];
b.y=a.y+y1[i];
if(check(b)){
vt[b.x][b.y]=tm+1;//更新到达时间
q.push(b);
}
}
}
}
}
int main(){
int t;
int i,j;
int nb;
scanf("%d",&t);
nb=0;
while(t--){
nb++;
memset(vt,0,sizeof(vt));
memset(use,0,sizeof(use));//初始化
v.clear();
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
getchar();
for(j=1;j<=m;j++){
scanf("%c",&s[i][j]);
if(s[i][j]=='P'){
a1.x=i;
a1.y=j;
}
else if(s[i][j]=='D'){
b1.x=i;
b1.y=j;
}
else if(s[i][j]=='*'){//保存传送门位置
c.x=i;
c.y=j;
v.push_back(c);
}
}
}
bfs();
printf("Case %d: ",nb);
if(!vt[b1.x][b1.y]){
printf("impossible\n");
}
else{
printf("%d\n",vt[b1.x][b1.y]-1);
}
}
return 0;
}

  

代码:

UVALive5966(bfs)的更多相关文章

  1. 图的遍历(搜索)算法(深度优先算法DFS和广度优先算法BFS)

    图的遍历的定义: 从图的某个顶点出发访问遍图中所有顶点,且每个顶点仅被访问一次.(连通图与非连通图) 深度优先遍历(DFS): 1.访问指定的起始顶点: 2.若当前访问的顶点的邻接顶点有未被访问的,则 ...

  2. 【BZOJ-1656】The Grove 树木 BFS + 射线法

    1656: [Usaco2006 Jan] The Grove 树木 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 186  Solved: 118[Su ...

  3. POJ 3278 Catch That Cow(bfs)

    传送门 Catch That Cow Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 80273   Accepted: 25 ...

  4. POJ 2251 Dungeon Master(3D迷宫 bfs)

    传送门 Dungeon Master Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 28416   Accepted: 11 ...

  5. Sicily 1215: 脱离地牢(BFS)

    这道题按照题意直接BFS即可,主要要注意题意中的相遇是指两种情况:一种是同时到达同一格子,另一种是在移动时相遇,如Paris在(1,2),而Helen在(1,2),若下一步Paris到达(1,1),而 ...

  6. Sicily 1048: Inverso(BFS)

    题意是给出一个3*3的黑白网格,每点击其中一格就会使某些格子的颜色发生转变,求达到目标状态网格的操作.可用BFS搜索解答,用vector储存每次的操作 #include<bits/stdc++. ...

  7. Sicily 1444: Prime Path(BFS)

    题意为给出两个四位素数A.B,每次只能对A的某一位数字进行修改,使它成为另一个四位的素数,问最少经过多少操作,能使A变到B.可以直接进行BFS搜索 #include<bits/stdc++.h& ...

  8. Sicily 1051: 魔板(BFS+排重)

    相对1150题来说,这道题的N可能超过10,所以需要进行排重,即相同状态的魔板不要重复压倒队列里,这里我用map储存操作过的状态,也可以用康托编码来储存状态,这样时间缩短为0.03秒.关于康托展开可以 ...

  9. Sicily 1150: 简单魔板(BFS)

    此题可以使用BFS进行解答,使用8位的十进制数来储存魔板的状态,用BFS进行搜索即可 #include <bits/stdc++.h> using namespace std; int o ...

随机推荐

  1. html5+PHP,websocket无法连接的问题(Call to undefined function socket_create())

    首先是配置文件的问题,打开extension=php_gd2.dll和extension=php_sockets.dll 扩展. 主要注意的是你当前系统使用的php版本和环境变量里面的php版本是否一 ...

  2. ci 配置ckeditor + ckfinder 无图片上传按钮

    一:配置路径有问题 {$base_url}assets/js/editor/ckfinder/ckfinder.html  --> http://www.cnblogs.com/assets/j ...

  3. Html br 标签

    Html br 标签 <html> <body> <!-- br标签:跳到下一行--> <p>内<br />容</p> 注:br ...

  4. 关于ashrpt中行源的CPU + Wait for CPU事件深入解读

    该等待事件并不包含在等待事件范围,而是出现在ash的具体行源中,如下: 标注语句的每次执行大约1小时,如下awr所示: 该sql语句的最后一层Insert如下: insert into ta_tf l ...

  5. Pandas截取列的一部分

    以股票代码为例: 型式为:6位数字+"."+交易所代码,如600028.SH 如只需保留前6位: pattern = '(\w+)(?:.SZ|.SH)$' df['股票代码'] ...

  6. opencv3.0之后IPLimage转换成MAT的问题

    转自http://www.cnblogs.com/edver/p/5187190.html IplImage * ipl = ...; cv::Mat m = cv::cvarrToMat(ipl); ...

  7. bzoj2091: [Poi2010]The Minima Game DP

    2091: [Poi2010]The Minima Game DP 链接 https://www.lydsy.com/JudgeOnline/problem.php?id=2091 思路 这类问题好迷 ...

  8. TCP协议三次握手、四次挥手

    TCP的概述 TCP 把连接作为最基本的对象,每一条 TCP 连接都有两个端点,这种断点我们叫作套接字(socket),它的定义为端口号拼接到 IP 地址即构成了套接字,例如,若 IP 地址为 192 ...

  9. 20165306 2017-2018-2《Java程序设计》课程总结

    课程总结 每周作业链接汇总: 预备作业一:我期望的师生关系 预备作业二:学习基础和C语言基础调查 预备作业三:Linux安装与学习 第一周作业:Java入门 第二周作业:基本数据类型与数组,运算符.表 ...

  10. spring-cloud-config-server——Environment Repository

    参考资料: https://cloud.spring.io/spring-cloud-static/spring-cloud-config/1.4.0.RELEASE/single/spring-cl ...