問題レポートにGDUT_冬季訓練ソリューション_問題レポートに話題I_G個人の問題解決

問題レポートにGDUT_冬季訓練ソリューション_問題レポートに話題I_G個人の問題解決

トピック:

あなたは、新しいロールプレイングを再生したいです。細胞番目のm×n個によって図世界地図メッシュ表現を形成します。セルの右、前方と後方への移動、左が、世界地図を離れることができない - のセル内の任意の役割は、4つの方向にセルから移動することができます。

いくつかのモンスターでは、細胞を生きて。ある時点で、あなたは近い彼のセルに複数の小さなステップやモンスターのステップdの数であってもよい場合は、彼はすぐにあなたを殺すためにオーバー走りました。

あなたは、ゲームフィールドの別のユニットに一つのユニットから生きています。この操作の数を実行するために必要な手順の適用、最小番号が見つかった場合、実現可能性を決定し。

エントリー

モンスター危険図の最大距離と大きさ - 最初の行は、3つの非正の整数N、M、およびd(0 <= N * M <= 200000,0 <= D <= 200000)を含有します。

次のN行はそれぞれm個の文字を含みます。これらの文字は、「S」に等しくすることができる「」、 『M』、 『F』「開始 『と』セルが空であり、入力に一度のみ表示されます」行わ。

輸出

ユニットの端から出発してユニットを作動させる場合は、ステップの出力の最小数は、この操作を実行するために必要。それ以外の場合は、出力 "-1。"

サンプル:
INPUT

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最初の最短経路が得られるが、2つの問題があります。

1.データの範囲は、データは、N * M <= 2E5、それを言うことが可能となるnは1であり、mは2E5である、[開く[2E5] [2E5]が、確かではないアレイは、バーストなるので、動的割り当てを与えられていますメモリは、または、情報の一次元アレイの二次元アレイを維持します

2.Mポイントが同時に複数のMに影響を与え、割り当ての問題が繰り返される場合は、この効果は、このような複雑性は上がるだろう、あなたはレコードが、より最近のM影響されているが、あまりにも減少しているかどうかにレプリカ配列を開くことができます最もまたはキューを使用します。キューは、カバレッジBFSモンスターに影響を与えるための手段と、インパクトの内側に置かれており、影響範囲の全てがnである場合はその効果プルーン、第1の方法ステップnより小さいことができます。





具体的に:簡単にハンドルに動的配列、キーはMの影響を取得する方法です、

最初のステップは、全てのMが、私は構造の形で格納された座標情報キュー内部に配置されています

typedef struct coordinate
{int x_;int y_;}coor;

そのようなアプローチは、モンスターをd + 1であることを確認することであるにキュー、剰余値が0は、その後、彼の拡散を始めるあります。

else if(ch=='M')
			{
				all[time][time1]=d+1;
				coor co_;
				co_.x_=time;
				co_.y_=time1;
				que.push(co_);
			}

彼らはすでにモンスターを持って説明したK、すでに次のk-1、ある場合ので、今、すべてのモンスター内部のキューに、始まり、その後、その2よりも周囲のすべての4つの格子小さいを開始することができます影響を受けた、今回私たちは、共感が大きい場合、この時間はスキップされなければならず、より多くの最近のモンスターは、その影響力を発揮したことを示す、余計ない、スキップします。

while(!que.empty())
	{
		coor co=que.front();
		if((co.x_+1<n)&&all[co.x_+1][co.y_]<all[co.x_][co.y_]-1)
		{
			all[co.x_+1][co.y_]=all[co.x_][co.y_]-1;
			co.x_++;
			que.push(co);
			co.x_--;
		}
		if((co.x_-1>=0)&&all[co.x_-1][co.y_]<all[co.x_][co.y_]-1)
		{
			all[co.x_-1][co.y_]=all[co.x_][co.y_]-1;
			co.x_--;
			que.push(co);
			co.x_++;
		}
		if((co.y_+1<m)&&all[co.x_][co.y_+1]<all[co.x_][co.y_]-1)
		{
			all[co.x_][co.y_+1]=all[co.x_][co.y_]-1;
			co.y_++;
			que.push(co);
			co.y_--;
		}
		if((co.y_-1>=0)&&all[co.x_][co.y_-1]<all[co.x_][co.y_]-1)
		{
			all[co.x_][co.y_-1]=all[co.x_][co.y_]-1;
			co.y_--;
			que.push(co);
			co.y_++;
		}
		que.pop();
	}

このステップが行われ、残りは通常の2次元空間BFSは最短経路を見つけることですが、私のアプローチは、影響を受けるポイント1せることです-パスを表現する方法を、D + 1、0ポイントは影響を受けませんがその長さは、私は負を用い、負の数と、この開始点への最短経路を表します。
そして、次のように完全なコードは次のとおりです。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <climits>
#include <queue>

#define ULL unsigned long long
using namespace std;

typedef struct coordinate
{int x_;int y_;}coor;
queue<coor>que;
int n,m,d;
int start_x,start_y,end_x,end_y;

int main()
{
	scanf("%d %d %d",&n,&m,&d);
	int all[n+1][m+1];
	memset(all,0,sizeof(all));
	getchar();
	for(int time=0;time<n;time++)
	{
		for(int time1=0;time1<m;time1++)
		{
			char ch;
			ch=getchar();
			if(ch=='S'){all[time][time1]=0;start_x=time;start_y=time1;}
			else if(ch=='F'){all[time][time1]=0;end_x=time;end_y=time1;}
			else if(ch=='.'){all[time][time1]=0;}
			else if(ch=='M')
			{
				all[time][time1]=d+1;
				coor co_;
				co_.x_=time;
				co_.y_=time1;
				que.push(co_);
			}
		}
		getchar();
	}
	//input finished;
	while(!que.empty())
	{
		coor co=que.front();
		if((co.x_+1<n)&&all[co.x_+1][co.y_]<all[co.x_][co.y_]-1)
		{
			all[co.x_+1][co.y_]=all[co.x_][co.y_]-1;
			co.x_++;
			que.push(co);
			co.x_--;
		}
		if((co.x_-1>=0)&&all[co.x_-1][co.y_]<all[co.x_][co.y_]-1)
		{
			all[co.x_-1][co.y_]=all[co.x_][co.y_]-1;
			co.x_--;
			que.push(co);
			co.x_++;
		}
		if((co.y_+1<m)&&all[co.x_][co.y_+1]<all[co.x_][co.y_]-1)
		{
			all[co.x_][co.y_+1]=all[co.x_][co.y_]-1;
			co.y_++;
			que.push(co);
			co.y_--;
		}
		if((co.y_-1>=0)&&all[co.x_][co.y_-1]<all[co.x_][co.y_]-1)
		{
			all[co.x_][co.y_-1]=all[co.x_][co.y_]-1;
			co.y_--;
			que.push(co);
			co.y_++;
		}
		que.pop();
	}
	//完成赋值,接下来该走普普通通板子bfs了
	if(all[start_x][start_y]!=0){printf("-1\n");}
	else
	{
		queue<coor>bfs_;
		coor start;
		start.x_=start_x;
		start.y_=start_y;
		bfs_.push(start);
		all[start_x][start_y]=-1;
		while(!bfs_.empty())
		{
			coor next=bfs_.front();
			bfs_.pop();

			if((next.x_+1<n)&& all[next.x_+1][next.y_]==0 )
			{
				all[next.x_+1][next.y_]=all[next.x_][next.y_]-1;
				next.x_++;
				bfs_.push(next);
				next.x_--;
			}
			if((next.x_-1>=0)&& all[next.x_-1][next.y_]==0 )
			{
				all[next.x_-1][next.y_]=all[next.x_][next.y_]-1;
				next.x_--;
				bfs_.push(next);
				next.x_++;
			}
			if((next.y_+1<m)&& all[next.x_][next.y_+1]==0 )
			{
				all[next.x_][next.y_+1]=all[next.x_][next.y_]-1;
				next.y_++;
				bfs_.push(next);
				next.y_--;
			}
			if((next.y_-1>=0)&& all[next.x_][next.y_-1]==0 )
			{
				all[next.x_][next.y_-1]=all[next.x_][next.y_]-1;
				next.y_--;
				bfs_.push(next);
				next.y_++;
			}
		}
		if(all[end_x][end_y]>=0)printf("-1");
		else printf("%d\n",-1-all[end_x][end_y]);
	}


    return 0;
}
リリース8元の記事 ウォンの賞賛0 ビュー115

おすすめ

転載: blog.csdn.net/DevourPower/article/details/103962920