+思考最短バリアント[USACO07OCT】障害物コースS(ロス・バレーP1649)

【USACO07OCT】障害物コースS

タイトル説明

1からなるN(1 <= N <= 100)正方形フィールドをX Nを検討

1枚のタイルによります。これらのタイルの一部は牛によってimpassibleであり、「x」をナビゲートするために挑戦され、この5によってフィールドにしてマークされます。
图略:
ベッシーは、位置Aでそのような分野で自分自身を発見し、順番に位置Bに移動したいですそこに塩ブロックをなめるします。牛のようにゆっくりと、製材生き物がオンにすると、当然のことながら、唯一の正方形のフィールドの端に平行に移動することが好きではありません。所与のフィールドのために、ベッシーは、任意の方向に向けて開始および終了することができるB.ザパスにAから任意のパスに90度ターンの最小数を決定します。ベッシーは彼女が塩なめるに取得することができます知っています。

グリッド内のN * N(1 <= N <= 100)、 'X' 表す格子が歩くことができない、 '' 格子は、歩くことができ表します。カルメン脂肪、したがって、悪いターン。今、点Aから点Bに移動し、少なくとも90度曲げを数回オンにする必要がありますか?

入力形式

整数Nの最初の行は、N個の文字の次のNラインは、文字のみが表示されます「」、 『X』、 『A』、 『B』、各文字がした後、上述マトリックス上記グリッドを示しますスペース。

[データ]スケール

2 <= N <= 100

出力フォーマット

整数:ターンの最小数。そうでない場合は、-1の出力に達します。


この問題は、すべてのパスBFS計算、およびすべての旋回経路の最小数を取得することができます。

しかし、あなたはまた、直接私がdijのアルゴリズムを使用して、最短を求めることができます。

最短異なる平均最短パスでこの質問は、3つのプロパティを持つそれぞれに最初のノードと同じ文言ではありません。

  1. ノード点座標x及びy
  2. 点fの方向
  3. ステアリングの最小数の開始点からこの点に来

違いは、ほとんどの判断であり、チームは、一般的に等号を再生していないかどうかを決定する際の一般的な最短のDijと、これは戦う必要があり、も同じパス場合、ポイントの方向が異なっていてもよく、その後、存在するかどうかを判断することができるのでこの点を横断し、それは異なり、コード注釈付き。

コード:

#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,int>
#define lson k<<1
#define rson k<<1|1
using namespace std;
const int N=10000100;
const int M=200100;
const LL mod=2e9+7;
char s[110][110];
int sx,sy,ex,ey,dis[110][110],n;
bool vis[110][110];
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
struct Node{
	int x,y,w,f;
	bool operator < (const Node& rhs) const{return w>rhs.w;}
};
void dij(){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++) dis[i][j]=2e9;
	}
	dis[sx][sy]=0;
	priority_queue<Node>qu;
	qu.push((Node){sx,sy,0,-1});
	while(!qu.empty()){
		Node n1=qu.top();
		qu.pop();
//		if(vis[n1.x][n1.y]) continue;//这个判断条件不能有 
		vis[n1.x][n1.y]=true;
		for(int i=0;i<=3;i++){
			int x=n1.x+dx[i];
			int y=n1.y+dy[i];
			if(x<1||x>n||y<1||y>n||s[x][y]=='x'||vis[x][y]) continue;
			if(n1.f==-1){
				dis[x][y]=1;
				qu.push((Node){x,y,1,i});
			}
			else{
				if(abs(n1.f-i)==2||n1.f==i){//不转向 
					if(dis[x][y]>=n1.w) dis[x][y]=n1.w,qu.push((Node){x,y,dis[x][y],i});
					//必须有等号 
				}
				else{//转向 
					if(dis[x][y]>=n1.w+1) dis[x][y]=n1.w+1,qu.push((Node){x,y,dis[x][y],i});
					//必须有等号 	
				}
			}
		}
	}
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			cin>>s[i][j];
			if(s[i][j]=='A') sx=i,sy=j;
			if(s[i][j]=='B') ex=i,ey=j;
		}
	}
	dij();
	if(dis[ex][ey]==2e9) cout<<-1<<endl;
	else cout<<dis[ex][ey]-1<<endl;
	return 0;
}

公開された264元の記事 ウォン称賛46 ビュー10000 +

おすすめ

転載: blog.csdn.net/qq_44291254/article/details/105347940