师傅又被妖怪抓走了

时间限制:1000 ms  |  内存限制:65535 KB
难度:3
 
描述

话说唐僧复得了孙行者,师徒们一心同体,共诣西方。自宝象国救了公主,承君臣送出城西,沿路饥餐渴饮,悟空便为师傅去化斋,等悟空回来,悟净慌慌张张的对悟空说:“不好了,不好了”,还没等悟净说完,悟空说:“师傅又被妖怪抓走了”,悟净:“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——师傅又被妖怪抓走了——————【双广搜】的更多相关文章

  1. nyoj999 师傅又被妖怪抓走了 (预处理+bfs+状态压缩)

    题目999 题目信息 执行结果 本题排行 讨论区 师傅又被妖怪抓走了 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描写叙述 话说唐僧复得了孙行者,师徒们一心同体,共诣西方.自宝 ...

  2. NYOJ999 师傅又被妖怪抓走了

    只记得当下的眼疼 , ok 各种数据也试了 , 就是 他娘的不对 , 我也是醉了 . 也是日了最野的狗 附上日了哮天犬的代码 , 这个题 先放放, 一段时间后再试试 , 明天开始状态压缩吧 .为期两天 ...

  3. openjudge 大师兄,师傅被妖怪抓走啦

    描述 孙悟空听到沙僧大喊一句:“大师兄,师傅被妖怪抓走啦!”于是孙悟空直追白骨精而去.孙悟空在一条长度为L的森林小路上飞奔,上面有L+1个整点,依次为0,1,2……L.白骨精会使用一种大范围的攻击法术 ...

  4. nyoj 999

    nyoj 999: 点击打开题目链接 题目思路,处理一下地图,把 D E 能看到的地方标记一下.然后就是暴力广搜一下.标记状态,因为同样在同一个点,但是你刚出发到达那点和找到D之后到达相同的点和找到E ...

  5. shu_1548 悟空问题(大哥,主妖怪抓走的朋友!)

    http://202.121.199.212/JudgeOnline/problem.php?cid=1078&pid=17 分析:  直接暴力了.. . 代码: #include <s ...

  6. nyoj 613 免费馅饼 广搜

    免费馅饼 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼.说来gameboy ...

  7. 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 ...

  8. nyoj 592 spiral grid(广搜)

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=592 解决以下问题后就方便用广搜解: 1.将数字坐标化,10000坐标为(0,0),这样就 ...

  9. nyoj 523 双向广搜

    题目链接: http://acm.nyist.net/JudgeOnline/problem.php?pid=523 #include<iostream> #include<cstd ...

随机推荐

  1. OO 抽象类与接口的区别

    抽象类与接口的区别 抽象类与接口的区别 一.抽象类:(抽象类适用于同一系列,并且有需要继承的成员) 概念: 1.使用abstract修饰: 2.抽象类中可以包含抽象方法: 3.抽象类只能被子类继承:( ...

  2. 类的互相包含------新标准c++程序设计

    #include<iostream> using namespace std; class A; class B{ public: void f(A* pt){}; } class A{ ...

  3. opencv.js小案例

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  4. [SinGuLaRiTy] 2017 百度之星程序设计大赛 初赛A

    [SinGuLaRiTy-1036] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 小C的倍数问题 Time Limit: 2000/100 ...

  5. 【bzoj4832】[Lydsy1704月赛]抵制克苏恩 期望dp

    Description 小Q同学现在沉迷炉石传说不能自拔.他发现一张名为克苏恩的牌很不公平.如果你不玩炉石传说,不必担心,小Q 同学会告诉你所有相关的细节.炉石传说是这样的一个游戏,每个玩家拥有一个 ...

  6. Java FileInputStream与FileReader的区别

    在解释Java中FileInputStream和FileReader的具体区别之前,我想讲述一下Java中InputStream和Reader的根本差异,以及分别什么时候使用InputStream和R ...

  7. css3中的自定义字体

    自定义字体 /*定义*/ @font-face { font-family: "icons"; src: url("icomoon.eot"); src: lo ...

  8. ob系列函数归纳

     输出控制函数(output control函数) flush — 刷新输出缓冲ob_clean — 清空(擦掉)输出缓冲区ob_end_clean — 清空(擦除)缓冲区并关闭输出缓冲ob_end_ ...

  9. Cboard 实现看板里面图表仪表盘之间的联动

    首先要了解Cboard的概念, 1.看板 2.图表 看Cborad的菜单知道了,首先先设计图表,可以展现未柱状图或者其它图片形式或者数据表格式.然后看板可以由多个图表组合而成. 需求如下: 看板包含两 ...

  10. Markdown 语法快速入门手册

    Markdown 是一种轻量级标记语言,能将文本换成有效的XHTML(或者HTML)文档,它的目标是实现易读易写,成为一种适用于网络的书写语言. Markdown 语法简洁明了,易于掌握,所以用它来写 ...