nyoj 999——师傅又被妖怪抓走了——————【双广搜】
师傅又被妖怪抓走了
- 描述
-
话说唐僧复得了孙行者,师徒们一心同体,共诣西方。自宝象国救了公主,承君臣送出城西,沿路饥餐渴饮,悟空便为师傅去化斋,等悟空回来,悟净慌慌张张的对悟空说:“不好了,不好了”,还没等悟净说完,悟空说:“师傅又被妖怪抓走了”,悟净:“NO!” ,悟空一脸茫然,悟净:“师傅和二师兄都被妖怪抓走了”。悟空(晕!)。为了防止悟空救人,妖怪先把唐憎和八戒分别藏起来,如果悟空在T分钟之后还没找到人,那必定是被妖怪吃掉了。假设悟空在一个n行m列的矩阵内,悟空在每一分钟可以走到上,下,左,右的其中的一个可以走的位置,每次只能走一步。我们把发现定义为可以直接看到对方,也就是说两个人在同一行或者同一列,并且中间没有障碍物或者没有其他人就可以看到对方。
- 输入
- 有多组测试数据,每组首先是三个正整数n , m (3<=n,m<=100), T,(0<=T<=100) 分别代表行数,列数,规定的时间。接下来n 行,每行 m 个字符。其中’ S ’ 代表悟空的位置,’ D ’代表师傅位置,’ E ’代表八戒的位置。并且保证都只有一个. ’ X ’代表墙 ,’ . ’代表空地 .
- 输出
- 每组先输出一行Case c:(c表示当前的组数,从1开始计数);
接下来一行,如果悟空可以在规定时间内找到两人,则输出最少需要的时间,否则输出-1。 - 样例输入
-
5 6 3
XXD...
....E.
....X.
....S.
......
5 6 3
XDX...
....E.
......
....S.
......
5 6 8
XXDX..
.XEX..
......
....S.
...... - 样例输出
-
Case 1:
-1
Case 2:
3
Case 3:
-1 解题思路:首先将图处理一下,处理成可以表示在某点可以找到某人或两人。然后在搜到某人后搜另外一个或者同时搜到两人。如果搜到其中一人,然后再搜另外一人。这就是双广搜,先搜一个中间结果,再在这个基础上搜另外未完成的结果。但是需注意,不是先搜到的就是最优结果。所以需要把能成功搜到两人的路径都搜一遍。取最小值。#include<bits/stdc++.h>
using namespace std;
char Map[105][105];
int mark[105][105];
int vis[105][105];
int f[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int n,m,ans,t;
const int INF=1e9;
struct Monkey{
int x,y;
int step;
};
bool CanTravle(int ti,int tj){ //判断是否可以走
if(Map[ti][tj]=='X'||Map[ti][tj]=='D'||Map[ti][tj]=='E'){
return 0;
}else{
return 1;
}
}
char trans(int i,int j,int cas){ //转化字符
if(cas&&Map[i][j]=='e'||(!cas&&Map[i][j]=='d')){
return 'o';
}
return cas ? 'd': 'e';
}
void Change(int si,int sj,int cas){ //把D、E所在的行列能走的变为d和e,把交叉点变为o
int i,j;
for(i=si+1;i<=n&&CanTravle(i,sj);i++)
Map[i][sj]=trans(i,sj,cas);
for(i=si-1;i>=1&&CanTravle(i,sj);i--)
Map[i][sj]=trans(i,sj,cas);
for(j=sj+1;j<=m&&CanTravle(si,j);j++)
Map[si][j]=trans(si,j,cas);
for(j=sj-1;j>=1&&CanTravle(si,j);j--)
Map[si][j]=trans(si,j,cas);
}
queue<Monkey>Q;
queue<Monkey>Qde;
int BFSde(int cas){ //在找到八戒或师父后找另外一个
Monkey st,tmp;
while(!Qde.empty()){
st=Qde.front();
Qde.pop();
if(st.step>t)
continue;
if(cas&&Map[st.x][st.y]=='e'||(!cas&&Map[st.x][st.y]=='d')||Map[st.x][st.y]=='o'){
return st.step;
}
int i,j,tx,ty,tsp;
for(i=0;i<4;i++){
tx=st.x+f[i][0];
ty=st.y+f[i][1];
if(tx<=n&&tx>=1&&ty<=m&&ty>=1&&(!vis[tx][ty])&&CanTravle(tx,ty)){
tsp=st.step+1;
vis[tx][ty]=1;
tmp.x=tx,tmp.y=ty,tmp.step=tsp;
Qde.push(tmp);
}
}
}
return INF;
}
void BFS(){ //找到八戒或师父或同时找到两人
Monkey st,tmp;
ans=INF;
while(!Q.empty()){
st=Q.front();
Q.pop();
if(st.step>t)
continue;
if(Map[st.x][st.y]=='o'){
ans=min(ans,st.step);
}else if(Map[st.x][st.y]=='e'){
while(!Qde.empty())
Qde.pop();
Qde.push(st);
memset(vis,0,sizeof(vis));
vis[st.x][st.y]=1;
ans=min(ans,BFSde(0));
}else if(Map[st.x][st.y]=='d'){
while(!Qde.empty())
Qde.pop();
Qde.push(st);
memset(vis,0,sizeof(vis));
vis[st.x][st.y]=1;
ans=min(ans,BFSde(1));
}
int tx,ty,tsp,i,j;
for(i=0;i<4;i++){
tx=st.x+f[i][0];
ty=st.y+f[i][1];
if(tx>=1&&tx<=n&&ty>=1&&ty<=m&&CanTravle(tx,ty)&&(!mark[tx][ty])){
mark[tx][ty]=1;
tsp=st.step+1;
tmp.x=tx,tmp.y=ty,tmp.step=tsp;
Q.push(tmp);
}
}
}
}
int main(){
int i,j,k,cnt=0;
Monkey st;
while(scanf("%d%d%d",&n,&m,&t)!=EOF){
memset(mark,0,sizeof(mark));
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
cin>>Map[i][j];
if(Map[i][j]=='S'){
st.x=i;
st.y=j;
st.step=0;
}
}
}
for(i=1;i<=n;i++){ //处理图
for(j=1;j<=m;j++){
if(Map[i][j]=='D'){
Change(i,j,1);
}else if(Map[i][j]=='E'){
Change(i,j,0);
}
}
}
while(!Q.empty())
Q.pop();
Q.push(st);
mark[st.x][st.y]=1;
BFS();
if(ans>t){
printf("Case %d:\n-1\n",++cnt);
}else{
printf("Case %d:\n%d\n",++cnt,ans);
}
}
return 0;
} /* 5 6 30
XDX...
....E.
...S..
......
...... 7 6 5
......
.D.X..
X.X...
X.....
X.X...
.E....
...S..
*/
nyoj 999——师傅又被妖怪抓走了——————【双广搜】的更多相关文章
- nyoj999 师傅又被妖怪抓走了 (预处理+bfs+状态压缩)
题目999 题目信息 执行结果 本题排行 讨论区 师傅又被妖怪抓走了 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描写叙述 话说唐僧复得了孙行者,师徒们一心同体,共诣西方.自宝 ...
- NYOJ999 师傅又被妖怪抓走了
只记得当下的眼疼 , ok 各种数据也试了 , 就是 他娘的不对 , 我也是醉了 . 也是日了最野的狗 附上日了哮天犬的代码 , 这个题 先放放, 一段时间后再试试 , 明天开始状态压缩吧 .为期两天 ...
- openjudge 大师兄,师傅被妖怪抓走啦
描述 孙悟空听到沙僧大喊一句:“大师兄,师傅被妖怪抓走啦!”于是孙悟空直追白骨精而去.孙悟空在一条长度为L的森林小路上飞奔,上面有L+1个整点,依次为0,1,2……L.白骨精会使用一种大范围的攻击法术 ...
- nyoj 999
nyoj 999: 点击打开题目链接 题目思路,处理一下地图,把 D E 能看到的地方标记一下.然后就是暴力广搜一下.标记状态,因为同样在同一个点,但是你刚出发到达那点和找到D之后到达相同的点和找到E ...
- shu_1548 悟空问题(大哥,主妖怪抓走的朋友!)
http://202.121.199.212/JudgeOnline/problem.php?cid=1078&pid=17 分析: 直接暴力了.. . 代码: #include <s ...
- nyoj 613 免费馅饼 广搜
免费馅饼 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼.说来gameboy ...
- nyoj 1022 最少步数【优先队列+广搜】
最少步数 时间限制:3000 ms | 内存限制:65535 KB 难度:4 描述 这有一个迷宫,有0~8行和0~8列: 1,1,1,1,1,1,1,1,1 1,0,0,1,0,0,1,0,1 ...
- nyoj 592 spiral grid(广搜)
题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=592 解决以下问题后就方便用广搜解: 1.将数字坐标化,10000坐标为(0,0),这样就 ...
- nyoj 523 双向广搜
题目链接: http://acm.nyist.net/JudgeOnline/problem.php?pid=523 #include<iostream> #include<cstd ...
随机推荐
- [转]Programmatically Register Assemblies in C#.
1. Introduction. 1.1 After publishing Programmatically Register COM Dlls in C# back in 2011, I recei ...
- 树莓派_实现摄像头的拍照、监控与录像(Raspiberry PI Camera 5W)
学无止境 前言:大家好,欢迎来到誉雪飞舞的博客园,我的每篇文章都是自己用心编写, 算不上精心但是足够用心分享我的自学知识,希望大家能够指正我,互相学习成长. 转载请注明:https://www. ...
- 第七篇 Python面向对象
类是对一群具有相同特征或者行为的事物的一个统称,是抽象的,不能直接使用,特征被称为属性,行为被称为方法,类就相当于制造飞机时的图纸,是一个模板,是负责创建对象的. 对象是由类创建出来的一个具体存在,可 ...
- JSP页面导出PDF格式文件
JSP页面导出PDF格式文件基本在前端页面可以全部完成 <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/ ...
- kali linux之被动信息收集(dns信息收集,区域传输,字典爆破)
公开可获取的信息,不与目标系统产生交互,避免留下痕迹 下图来自美军方 pdf链接:http://www.fas.org/irp/doddir/army/atp2-22-9.pdf 信息收集内容(可利用 ...
- 【转】plsql 永久注册码适用个版本
源地址:https://blog.csdn.net/sinat_33142609/article/details/72540025 注册码:Product Code:4t46t6vydkvsxekkv ...
- Java面向对象之内部类(匿名内部类)
一.基础概念 匿名内部类:简化书写的内部类.其实匿名内部类就是一个子类对象. 前提:内部类需要继承或者实现外部的类或者接口. 格式:new 父类或者接口(){定义子类的内容} 二.将内部类定义到局部的 ...
- Java面向对象之关键字this 入门实例
一.基础概念 1.关键字this是指:哪个对象调用this所在的函数.this就指向当前这个对象. 2.用法: (1).this关键字可以解决:构造函数私有化问题. 注意:构造函数只能被构造函数调用, ...
- 如何离线Windows server 2008R2 激活教程?
服务器离线激活,可是费了老大劲了,不过最后还不是离线激活,还必须联网,也或许你运气好,不联网也能激活. 如果由于种种原因不能有线的话,那就可以试试这种方法了. 1.首先,开启无线LAN服务.(不会开启 ...
- Unity---动画系统学习(6)---Avatar Mask动画融合、Layers动画分层、IK反向动力学
1. 介绍 Avatar Mask(动画融合) 前面我们一直介绍的都是动画混合,一般用于解决边跑边转弯的问题.而动画融合一般用于解决例如边跑边挥手的问题. 简单说就是让跑步去控制腿的骨骼,挥手控制手的 ...