私はGジムのアンソロジー2019_GDUT_新生児トピックス - 101755H

トピック:

新しいRPGをプレイ。その中の世界地図は、n×m個のセルのグリッドで表されます。前後に、右、左のセルに、しかし、世界地図を残さない - いくつかのセルに滞在し、任意の演奏文字が四方にこのセルから移動することができます。

モンスターは、いくつかの細胞に住んでいます。時間のいくつかの瞬間にあなたがDのステップ以下では、いくつかのモンスターによって到達可能であるセル内にある場合、彼はすぐに実行され、あなたを殺します。

あなたは別のゲームフィールドの一つのセルから生きて取得する必要があります。それが可能かどうかを判断し、YESの場合、それを行うために必要な手順の最小数を見つけます。

入力は、
モンスターが危険であるれるマップのサイズとの最大距離-最初の行は、3つの非負整数N、M及びD(2≤N・M≤200000、0≤D≤200000)を含有します。

次のn行の各々は、m個の文字を含みます。これらの文字は等しいことができます«»、«M»、«S»と空のセルを示す«F»、モンスターとセル、セルとセルの仕上げを開始し、それに対応。スタートとフィニッシュ細胞は空で、正確に一度の入力で提示されています。

出力
には、仕上げセルに開始セルからそれを行うために必要な手順の出力最小数を生きて取得することが可能です。それ以外の場合は、出力
«-1»。
入力
5 7 1
SM ... M
...
...
M ... M ...
... F
出力
12
入力
7 6 2
S ...
... M ...
...
... M
...
M ...
... Fの
出力
11
入力
7 6 2
S ...
... M ...
...
...
... M
M ...
... Fの
出力
-1
入力
4 4 2
M ...
.S ...
...
... Fの
出力
-1

分析:BFS、モンスターのBFS最初の場所、すべてのBFSの起点に、その後行く、とないとしてマークされたマップ内のモンスターDステップ。開始時間は直接モンスター出力の範囲内であったかもしれない-1。モンスターがいない別のモンスターからカバーに注意するためBFS時間は、モンスターは、他のモンスターの中に閉じ込めすることができる状況に注意を払うオープン2つのキュー、そこに各モンスターのための事前情報に格納されている、モンスターを行う必要があります範囲のDFSは、他のモンスターを拡大する、そこから対応する点で保存し、あなたはより多くのD-ステップ検索より再び必要はありません。

コード:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue> 
struct node
{
	int x,y;
};
using namespace std;
int M[2000*2000],D,n,m,xs,ys,xf,yf,ans=2000000000;
int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
queue <node> q,p;
void bfs1()
{
	int (*a)[m]=(decltype(a))M;
	int x,y;
	while (!p.empty())
	{
		node f = p.front();
		node pre=q.front();
		for (int i=0;i<4;i++)
		{
			x=f.x+dx[i];
			y=f.y+dy[i];
			if (abs(x-pre.x)+abs(y-pre.y)<=D && a[x][y]==0 && x>0 && y>0 && x<=n && y<=m)
			{
				p.push(node{x,y});
				a[x][y]=-2;
				q.push(pre);
			}
		}
		p.pop();
		q.pop();
	}
}
void bfs(int x1,int y1)
{
	int (*a)[m]=(decltype(a))M;
	int x,y;
	p.push(node{x1,y1});
	a[x1][y1]=1;
	while (!p.empty())
	{
		for (int i=0;i<4;i++)
		{
			x=p.front().x+dx[i];
			y=p.front().y+dy[i];
			if (a[x][y]==0 && x>0 && y>0 && x<=n && y<=m)
			{
				if (x==xf && y==yf)
				{
					a[x][y]=a[p.front().x][p.front().y]+1;
					if (ans>a[x][y])
					ans=a[x][y]-1;
					return;
				}
				p.push(node{x,y});
				a[x][y]=a[p.front().x][p.front().y]+1;
			}
		}
		p.pop();
	}
}
int main()
{
	cin>>n>>m>>D;
	int (*a)[m]=(decltype(a))M;
	char s[300000];
	for (int i=1;i<=n;i++)
	{
		cin>>s;
		for (int j=0;j<m;j++)
		{
			if (s[j]=='M')
			{
				a[i][j+1]=-1;
				q.push(node{i,j+1});
				p.push(node{i,j+1});
			}
			if (s[j]=='S') xs=i,ys=j+1;
			if (s[j]=='F') xf=i,yf=j+1;
		}
	}
	bfs1();
	if (a[xs][ys]==0)
	bfs(xs,ys);
	if (a[xf][yf]>0) cout<<ans;
	else cout<<-1;
}
公開された14元の記事 ウォンの賞賛0 ビュー303

おすすめ

転載: blog.csdn.net/qq_39581539/article/details/103964429