2018年东北农业大学春季校赛 wyh的吃鸡

链接: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的地图,每个字符都是上面的一种,并且保证只有一个起点,只有一块安全区域。

输出描述:

对于每组测试数据,先输出能否到达,能的话输出YES,然后换行输出最短时间,如果不能的话直接输出NO
示例1

输入

3
2 3
.X
S.
2 3
.X
SC
2 4
.X
S.

输出

NO
YES
3
YES
4

思路:
启发式搜索,参照SPFA最小堆优化。
代码:
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define read(x) scanf("%lld",&x)
  4 #define out(x) printf("%lld",&x)
  5 #define cfread(x) scanf("%I64d",&x)
  6 #define cfout(x) printf("%I64d",&x)
  7 #define mian main
  8 #define min(x,y) (x<y?x:y)
  9 #define max(x,y) (x<y?y:x)
 10 #define f(i,p,q,t) for(i=p;i<q;i+=t)
 11 #define MAXN 110000
 12 #define inf 0x3f3f3f3f
 13 #define mem(x,t) memset(x,t,sizeof(x));
 14 #define T true
 15 #define F false
 16 #define def -1*inf
 17 typedef long long ll;
 18 typedef long long LL;
 19 typedef double dd;
 20 char s[300][300];
 21 int v[300][300][2];
 22 int dx[]={-1,1,0,0};
 23 int dy[]={0,0,-1,1};
 24 struct Data{
 25     int x,y;
 26     int bs;
 27     int qc;
 28     bool operator<(const Data &pt)const{
 29         return this->bs>pt.bs;
 30     }
 31 };
 32 priority_queue<Data> team;
 33 void deal(){
 34     int n,m;
 35     scanf("%d%d",&n,&m);
 36     memset(v,-1,sizeof(v));
 37     for(int i=1;i<=n;i++)
 38         scanf("%s",s[i]+1);
 39     Data pt;
 40     int qdx,qdy;
 41     for(int i=1;i<=n;i++)
 42         for(int j=1;j<=n;j++)
 43             if(s[i][j]=='S')
 44                 qdx=i,qdy=j;
 45     pt.x = qdx;
 46     pt.y = qdy;
 47     pt.bs = 0;
 48     pt.qc = 0;
 49     v[pt.x][pt.y][pt.qc] = pt.bs;
 50     while(!team.empty())
 51         team.pop();
 52     team.push(pt);
 53     int ans = -1;
 54     while(!team.empty()){
 55         pt =team.top();
 56         team.pop();
 57         if(pt.bs>ans&&ans!=-1)
 58             break;
 59     //    cout<<pt.x<<" "<<pt.y<<" "<<pt.bs<<endl; 
 60         if(pt.bs>m)
 61             break;
 62         if(s[pt.x][pt.y]=='X'){
 63             if(ans==-1||pt.bs<ans)
 64                 ans = pt.bs;
 65         }
 66         for(int i=0;i<4;i++){
 67             int nx = pt.x+dx[i];
 68             int ny = pt.y+dy[i];
 69             if(nx<=0||ny<=0||nx>n||ny>n)
 70                 continue;
 71             if(s[nx][ny]=='O')
 72                 continue;
 73             int yc = 0;
 74             yc = pt.qc;
 75             if(s[nx][ny]=='C'){
 76                 yc = 1;
 77             }
 78             Data pd;
 79             pd.x = nx,pd.y = ny;
 80             pd.qc = yc;
 81             pd.bs = pt.bs + 2 - pt.qc;
 82             if(v[pd.x][pd.y][pd.qc]<=pd.bs&&v[pd.x][pd.y][pd.qc]!=-1){
 83                 continue;
 84             }
 85             //cout<<"\t"<<nx<<" "<<ny<<" "<<pd.bs<<endl;
 86             v[pd.x][pd.y][pd.qc] = pd.bs;
 87             team.push(pd);
 88         }
 89     }
 90     if(ans<=m&&ans>-1)
 91          printf("YES\n%d\n",ans);    
 92     else
 93         printf("NO\n");
 94 }
 95 int main(){
 96     int t;
 97     scanf("%d",&t);
 98     while(t--)
 99         deal();
100     return 0;
101 }

 

转载于:https://www.cnblogs.com/xfww/p/8727711.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值