链接:
https://www.nowcoder.com/acm/contest/93/H
来源:牛客网
来源:牛客网
题目描述
最近吃鸡游戏非常火,你们wyh学长也在玩这款游戏,这款游戏有一个非常重要的过程,就是要跑到安全区内,否则就会中毒持续消耗血量,我们这个问题简化如下
假设地图为n*n的一个图,图中有且仅有一块X的联通快代表安全区域,有一个起点S代表缩圈的时候的起点,图中C代表的是车(保证车的数量小于等于100),标记为.的代表空地,可以任意通过,O代表障碍物不能通过。每次没有车的时候2s可以走一个格(只能走自己的上下左右4个方向),有车的话时间为1s走一个格
现在告诉你最多能坚持的时间为t秒,问你在t秒内(含t秒)能否从s点到达安全区域,能的话输出YES,并且输出最短时间,不能的话输出NO
输入描述:
输入第一行一个整数T(1<=T<=10) 接下来有T组测试数据,每组测试数据输入2个数n和k(1<=n<=100,1<=k<=10^9) 接下来n行,每行n个字符,代表对应的n*n的地图,每个字符都是上面的一种,并且保证只有一个起点,只有一块安全区域。
题解:
有两种情况,1.从起点到车,开车到终点。2.从起点走到终点。
从起点出发遍历整张图,遇到车标记一下距离,
从终点遍历整张图,遇到车标记一下,这里要注意
终点是一个联通块,因此把联通块中的点全部加入队列中然后bfs
代码:
#include<bits/stdc++.h>
using namespace std;
char t[1005][1005];
int x1,y2;
int d[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
bool is[102][102];
int d1[105][105],d2[105][105],n,k;
struct node
{
int x,y,step;
};
queue<node>P;
void bfs(int k)
{
while(!P.empty())
{
node e=P.front();P.pop();
if(t[e.x][e.y]=='C')
{
if(k==2)d1[e.x][e.y]=e.step;
else d2[e.x][e.y]=e.step*2;//走路时间加倍
}
for(int i=0;i<4;i++)
{
int x=e.x+d[i][0],y=e.y+d[i][1];
if(x>=0&&x<n&&y>=0&&y<n&&!is[x][y]&&t[x][y]!='O')
{
node r;r.x=x,r.y=y,r.step=e.step+1;
P.push(r);
is[x][y]=1;
}
}
}
}
int bfs1()
{
memset(is,0,sizeof(is));
node h;h.x=x1,h.y=y2,h.step=0;
P.push(h);
while(!P.empty())
{
node e=P.front();P.pop();
if(t[e.x][e.y]=='X')
{
return e.step*2;
}
for(int i=0;i<4;i++)
{
int x=e.x+d[i][0],y=e.y+d[i][1];
if(x>=0&&x<n&&y>=0&&y<n&&!is[x][y]&&t[x][y]!='O')
{
node r;r.x=x,r.y=y,r.step=e.step+1;
P.push(r);
is[x][y]=1;
}
}
}
return 1e9;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
for(int i=0;i<105;i++)
for(int j=0;j<105;j++)
d1[i][j]=d2[i][j]=1e9;
scanf("%d%d",&n,&k);
for(int i=0; i<n; i++)
scanf("%s",&t[i]);
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
if(t[i][j]=='S')x1=i,y2=j;
node e;e.x=x1,e.y=y2;e.step=0;
P.push(e);
memset(is,0,sizeof(is));
is[x1][y2]=1;
bfs(1);
memset(is,0,sizeof(is));
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(t[i][j]=='X')
{
node e;e.x=i,e.y=j,e.step=0;
P.push(e);
is[i][j]=1;
}
}
bfs(2);
int ans1=bfs1();
while(!P.empty())P.pop();
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(t[i][j]=='C')//注意并不是每一辆车都能走得到,因此要初始化d位无穷大
{
ans1=min(ans1,d1[i][j]+d2[i][j]);
}
}
if(ans1<=k) printf("YES\n%d\n",ans1);
else printf("NO\n");
}
return 0;
}