【BZOJ】1687: [Usaco2005 Open]Navigating the City 城市交通(bfs)

http://www.lydsy.com/JudgeOnline/problem.php?id=1687

bfs后然后逆向找图即可。因为题目保证最短路唯一

 

#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
#define rep(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getint()
#define print(a) printf("%d", a)
#define dbg(x) cout << #x << " = " << x << endl
#define printarr2(a, b, c) for1(i, 1, b) { for1(j, 1, c) cout << a[i][j]; cout << endl; }
#define printarr1(a, b) for1(i, 1, b) cout << a[i]; cout << endl
inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
inline const int max(const int &a, const int &b) { return a>b?a:b; }
inline const int min(const int &a, const int &b) { return a<b?a:b; }

const int N=100, Q=N*N, dx[]={-1, 1, 0, 0}, dy[]={0, 0, -1, 1};
int mp[N][N], n, m, f[N][N], front, tail, ans1[N], ans2[N], cnt, X, Y, XX, YY;
char s[N];
struct dat { int x, y; }q[Q];
void bfs() {
	front=tail=0;
	q[tail].x=X, q[tail++].y=Y;
	CC(f, 0x3f); f[X][Y]=0;
	while(tail!=front) {
		dat &t=q[front++]; if(front==Q) front=0;
		int x=t.x, y=t.y, d=f[x][y];
		rep(i, 4) {
			int fx=dx[i]+x, fy=dy[i]+y;
			if(fx<1 || fy<1 || fx>n || fy>m || !mp[fx][fy] || f[fx][fy]<=d+1) continue;
			f[fx][fy]=d+1;
			q[tail].x=fx, q[tail++].y=fy; if(tail==Q) tail=0;
		}
	}
	int x=XX, y=YY, now=-1, tot=0;
	while(!(x==X && y==Y)) {
		rep(i, 4) {
			int fx=dx[i]+x, fy=dy[i]+y;
			if(fx<1 || fy<1 || fx>n || fy>m || !mp[fx][fy] || f[fx][fy]!=f[x][y]-1) continue;
			if(mp[fx][fy]==1) ++tot;
			if(now!=i && now!=-1) {
				ans1[++cnt]=now;
				ans2[cnt]=tot;
				tot=0;
			}
			now=i;
			x=fx, y=fy;
		}
	}
	ans1[++cnt]=now; ans2[cnt]=tot+1;
}

int main() {
	read(n); read(m); n=n*2-1, m=m*2-1;
	for1(i, 1, n) {
		scanf("%s", s+1);
		for1(j, 1, m) {
			if(s[j]=='+') mp[i][j]=1;
			else if(s[j]=='S') X=i, Y=j, mp[i][j]=3;
			else if(s[j]=='E') XX=i, YY=j, mp[i][j]=4;
			else if(s[j]=='.') mp[i][j]=0;
			else mp[i][j]=2;
		}
	}
	bfs();
	for3(i, cnt, 1) {
		char c='H';
		if(ans1[i]==2) c='E';
		else if(ans1[i]==3) c='W';
		else if(ans1[i]==1) c='N';
		else if(ans1[i]==0) c='S';
		printf("%c %d\n", c, ans2[i]);
	}
	return 0;
}

 

 


 

 

Description

    由于牛奶市场的需求,奶牛必须前往城市,但是唯一可用的交通工具是出租车.教会奶牛如何在城市里打的.
    给出一个城市地图,东西街区E(1≤E≤40),南北街区N(1≤N≤30).制作一个开车指南给 出租车司机,告诉他如何从起点(用S表示)到终点(用E表示).每一个条目用空格分成两部分,第一个部分是方向(N,E,S,W之一),第二个是一个整 数,表示要沿着这个方向开几个十字路口.如果存在多条路线,你应该给出最短的.数据保证,最短的路径存在且唯一.    地图中“+”表示十字路口,道路 用“I”和“一”表示.建筑和其他设施用“.”表示.下面是一张地图:
 
 
    出租车可以沿着东,北,西,北,东开两个十字路口,以此类推.具体将由样例给出

Input

    第1行:两个用空格隔开的整数N和E.

    第2到2N行:每行有2E-I个字符,表示地图.

Output

    每行有一个表示方向的字母和一个表示要开几个十字路口的数字表示.

Sample Input

 

Sample Input

 

Sample Output

E 1
N 1
W 1
N 1
E 2
S 1
E 3
S 1
W 1

HINT

Source

转载于:https://www.cnblogs.com/iwtwiioi/p/3983248.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值