bzoj 1687: [Usaco2005 Open]Navigating the City 城市交通 bfs

版权声明:本文为博主原创文章,转载请联系博主。 https://blog.csdn.net/everlasting_20141622/article/details/77193439

题目链接


bfs时,对于每个点,显然最多只能访问一次,并且只要访问到了就一定是最短路径

记录一下到达每个点的步数,最后从终点每次找周围步数比它小1的点,就可以找到我们需要的那个路径

已经知道路径了,反着搞回去就可以了,每次判断一下行走方向是否改变就好

懒得反着记录答案,所以用了个双向队列,真是方便啊


代码:

#include<iostream>
#include<cstdio>
#include<queue>
#include<deque>
#include<vector>
#include<algorithm>
#include<cstring>

#define inf 999999999
#define ll long long

using namespace std;

struct point{
	int x,y;
	friend bool operator == (point a,point b){
		return (a.x==b.x && a.y==b.y);
	}
};

struct node{
	char way;
	int num;
};

point s,e;
int n,m;
int a[110][110];
int dis[110][110];
queue<point>q;
int tox[4]={-1,0,1,0};
int toy[4]={0,1,0,-1};
deque<node>ans;

int main(){
	scanf("%d%d\n",&n,&m);
	n=n*2-1;
	m=m*2-1;
	for(int i=1; i<=n; i++){
		for(int j=1; j<=m; j++){
			dis[i][j]=-1;
			char c;
			c=getchar();
			if(c=='.')continue;
			else if(c=='+')a[i][j]=2;
			else if(c=='S')s.x=i,s.y=j,a[i][j]=2;
			else if(c=='E')e.x=i,e.y=j,a[i][j]=2;
			else a[i][j]=1;
		}getchar();
	}
	dis[s.x][s.y]=0;
	point t;
	t=s;
	q.push(t);
	while(!q.empty()){
		t=q.front();
		q.pop();
		if(t==e)break;
		for(int i=0; i<4; i++){
			point t1=t;
			t1.x+=tox[i];
			t1.y+=toy[i];
			if(t1.x<1 || t1.x>n || t1.y<1 || t1.y>m || a[t1.x][t1.y]==0 || dis[t1.x][t1.y]!=-1)continue;
			dis[t1.x][t1.y]=dis[t.x][t.y]+1;
			q.push(t1);
		}
	}
	int last=-1;
	int sum=0;
	t=e;
	while(1){
		if(t==s){
			node tt;
			if(last==0)tt.way='S';
			if(last==1)tt.way='W';
			if(last==2)tt.way='N';
			if(last==3)tt.way='E';
			tt.num=sum;
			ans.push_front(tt);
			break;
		}
		int to;
		if(a[t.x][t.y]==2)sum++;
		for(int i=0; i<4; i++){
			point t1=t;
			t1.x+=tox[i];
			t1.y+=toy[i];
			if(t1.x<1 || t1.x>n || t1.y<1 || t1.y>m || a[t1.x][t1.y]==0 || dis[t1.x][t1.y]!=dis[t.x][t.y]-1)continue;
			to=i;
			break;
		}
		if(last!=to){
			if(last!=-1){
				node tt;
				if(last==0)tt.way='S';
				if(last==1)tt.way='W';
				if(last==2)tt.way='N';
				if(last==3)tt.way='E';
				tt.num=sum-1;
				ans.push_front(tt);
				sum=1;
			}
			last=to;
		}
		t.x+=tox[to];
		t.y+=toy[to];
	}
	for(int i=0; i<ans.size(); i++){
		printf("%c %d\n",ans[i].way,ans[i].num);
	}
	
	return 0;
}


展开阅读全文

Navigating the City

12-16

DescriptionnnA dip in the milk market has forced the cows to move to the city. The only employment available is in the venerable field of taxi-driving. Help the cows learn their way around the city. nnGiven a city map with E (1 <= E <= 40) east/west street locations and N (1 <= N <= 30) north/south street locations, create instructions for a taxi driver to navigate from the start of his route (marked 'S') to the end (marked 'E'). Each instruction is a direction (one of 'N', 'E', 'S', or 'W') followed by a space followed by an integer that tells how many blocks to drive in that direction. If multiple routes are available, your program should output the shortest route. The shortest route is guaranteed to exist and be unique. nnThe map is depicted as a grid of '+'s that represent intersections and a set of roads depicted as '-' and '|'. Buildings and other obstacles are shown as '.'s. Here is a typical map: n+-+-+.+-+-+nn|...|.....|nn+-+.+-+-+-+nn..|.......|nnS-+-+-+.E-+nnThe taxi should go east, north, west, north, east two blocks, and so on. See the output format and sample solution below for its complete route.nInputnn* Line 1: Two space-separated integers, N and E. nn* Lines 2..2*N: These lines each contain 2*E-1 characters and encode the map of the street. Every other input line gives the data for the east/west streets; the remaining lines show the north/south streets. The format should be clear from the example.nOutputnn* Lines 1..?: Each line contains a direction letter and a number of blocks to travel in that direction.nSample Inputnn3 6n+-+-+.+-+-+n|...|.....|n+-+.+-+-+-+n..|.......|nS-+-+-+.E-+nSample OutputnnE 1nN 1nW 1nN 1nE 2nS 1nE 3nS 1nW 1 问答

没有更多推荐了,返回首页