1. 程式人生 > >2018年東北農業大學春季校賽 H why的吃雞

2018年東北農業大學春季校賽 H why的吃雞

連結:點選開啟連結

題目描述

最近吃雞遊戲非常火,你們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

解題 思路:開一個dis陣列 表示從起點到當前這個點開車和不開車情況下的最小時間花費,如果當我到達一個點有最小值出現的時候,我就更新一下這個點,並加入到佇列裡,因為如果你一開始更新不是最小值的話,你就有可能同一個點入隊多次,造成超時的結果,所以你得用優先佇列。最後就是安全區不一定就一個點。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<iostream>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=110;
int n,m,t,dis[maxn][maxn][2],sx,sy,ex,ey;
char ch[maxn][maxn];
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
typedef struct Node{
	int x,y,flag,time;
	bool operator < (const Node &a) const{
		return time>a.time;
	}
}node;
bool check(int x,int y){
	if(x>=0&&x<n&&y>=0&&y<n)
		return 1;
	return 0;
}
int main(){
	int i,j;
	scanf("%d",&t);
	while(t--){
		scanf("%d%d",&n,&m);
		memset(dis,inf,sizeof(dis));
		for(i=0;i<n;i++){
			scanf("%s",ch[i]);
			for(j=0;j<n;j++){
				if(ch[i][j]=='S'){
					sx=i,sy=j;
				}
			}
		}
		dis[sx][sy][0]=0;
		priority_queue<node> qu;
		while(!qu.empty()) qu.pop();
		node no,po;
		no.x=sx;no.y=sy;no.flag=0;no.time=0;
		dis[no.x][no.y][0]=0;
		qu.push(no);
		while(!qu.empty()){
			no=qu.top();qu.pop();
			if(no.time>m) continue;
			for(i=0;i<4;i++){
				int xx=dx[i]+no.x;
				int yy=dy[i]+no.y;
				if(check(xx,yy)&&ch[xx][yy]!='O'){
					if(ch[xx][yy]=='C'){
						po.flag=1;
					}
					else
						po.flag=no.flag;
					if(no.flag) po.time=no.time+1;
					else po.time=no.time+2;
					if(po.time<dis[xx][yy][po.flag]){
						dis[xx][yy][po.flag]=po.time;
						po.x=xx;po.y=yy;
						qu.push(po);
					}
				}
			}
		}
		int ans=inf;
		for(i=0;i<n;i++){
			for(j=0;j<n;j++){
				if(ch[i][j]=='X'){
					ans = min(ans,min(dis[i][j][0], dis[i][j][1]));
				}
			}
		}
		if(ans>m){
			printf("NO\n");
		}
		else{
			printf("YES\n");
			printf("%d\n",ans);
		}
	}
	return 0;
}