ACdream P1242 Driving Straight

4 篇文章 0 订阅
4 篇文章 0 订阅

Driving Straight

Special Judge Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others)
Problem Description

      The city where Peter lives has the form of the rectangle with M streets running from east to west and N streets running from north to south. Recently, because of preparations for the celebration of the city’s 3141-st birthday, some street sectors has been closed for driving.

      Peter lives in the house next to point (1, 1) and works next to the point (N, M ). He always drives from home to work by his car using the shortest possible path. Of course, he can’t drive through closed sectors. Since there can be many shortest pathes between his house and his work, he may choose any. 

      But Peter doesn’t like to turn (he is an inexperienced driver), so he wants to choose the path using the following algorithm: starting from the point (1, 1) he drives either northwards, or eastwards (wherever there is the shortest path available, if there are both, he may choose any). Whenever he comes to the junction he must decide where to go. If there is only one direction he can drive to stay on the shortest path, he must choose that direction. In the other case he would like to choose the direction giving priority to driving forward, that is, if he can drive forward and still stay on some shortest path, he would go forward. If he can’t drive forward to stay on the shortest path, he would choose any available direction. 

      Help Peter to create the path from his house to his work using the rules described.

Input
      The first line of the input file contains integer numbers M and N (2 ≤ M, N ≤ 400).
      Next 2M − 1 lines contain 2N − 1 characters each, representing the city map. House blocks are marked with spaces, junctions with ‘+’, open sectors with ‘-’ and ’|’, closed sectors with spaces. Peter’s house is at the lower-left corner of the map, his work is at the upper-right corner.
Output
      On the first line of the output file print the direction Peter should choose first, ‘N’ or ‘E’. On the second line output the sequence of latin letters ‘F’, ‘L’ and ‘R’ representing Peter’s behaivour on junctions — go forward, turn left or right respectively. If there are several paths Peter can choose from, output any. You must output Peter’s action on the junction even if he has no choice due to closed streets. It is guaranteed that there will always be the way for Peter to get from home to work.
Sample Input
4 4
+-+ +-+
| |   |
+ +-+-+
|   |
+-+-+-+
|     |
+-+-+-+
Sample Output
N
RFLRL
Source
Andrew Stankevich Contest 4

广搜题目,从终点逆推,每个点每个方向是否是最短路都可以标记出来,有不少细节需要自己处理好,比如矩阵化图,标记已经搜过的点等。总的来说就是一道水题。


代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<string>
#include<cstring>
#include<algorithm>
#include<fstream>
#include<queue>
#include<stack> 
#include<vector>
#include<cmath>
#include<iomanip>
#define rep(i,n) for(i=1;i<=n;i++)
#define MM(a,t) memset(a,t,sizeof(a))
#define INF 1e9
typedef long long ll;
#define mod 1000000007
using namespace std;
int edge[700000],nxt[700000],fir[200000],lst[200000];
int n,m,n2,ST,TR,vis[200000];
bool f[200000][4];
queue<int> qu;
void addedge(int s,int e){
  edge[++n2]=e;
  if(fir[s]==-1){fir[s]=n2; lst[s]=n2;}
  else          {nxt[lst[s]]=n2; lst[s]=n2;}	
}
int getnode(int x,int y){
  x=(x+1)/2;
  y=(y+1)/2;
  return (x-1)*m+y;
} 
int getdir(int s,int e){
  if(s==e+1) return 0;
  if(s==e+m) return 1;
  if(s==e-1) return 2;
  if(s==e-m) return 3;	
}
int getnext(int x,int dir){
  switch(dir){
    case 0:return x-1;
	case 1:return x-m;
	case 2:return x+1;
	case 3:return x+m;	
  }	
}
int main()
{
	int i,j,dir,len;
	char st[1000];

    while(scanf("%d%d",&n,&m)!=EOF){
   	  n2=0; MM(fir,-1); MM(nxt,-1); MM(lst,-1); MM(vis,0);
      ST=getnode(2*n-1,1); TR=getnode(1,2*m-1); MM(f,0);
      getchar();
      for(i=1;i<=2*n-1;i++){
      	cin.getline(st,2*m);
      	len=strlen(st);
        if(len!=2*m-1){
          for(j=len;j<2*m-1;j++) st[j]=' ';
		  st[2*m-1]='\0';	
        }
   	    if(i%2){
   	      int s,e;
  		  for(j=1;j<=2*(m-1)-1;j+=2)
		  if(st[j]!=' '){
  		    s=getnode(i,j); e=getnode(i,j+2);
			addedge(s,e);
			addedge(e,s);	
  		  }    
        }
        else{
 	      int s,e;
  		  for(j=0;j<=2*(m-1);j+=2)
		  if(st[j]!=' '){
  		    s=getnode(i-1,j+1); e=getnode(i+1,j+1);
			addedge(s,e);
			addedge(e,s);	
  		  }
        }	
	  }//作图 
	  while(!qu.empty()) qu.pop();
	  qu.push(TR);
	  vis[TR]=1;
	  while(!qu.empty()){
  	    int s,e=qu.front(); qu.pop();
  	    if(e==ST) break;
		for(i=fir[e];i!=-1;i=nxt[i])
		{
		  s=edge[i];
		  if(vis[s]==2) continue;
		  f[s][getdir(s,e)]=1;
		  if(!vis[s]){
            vis[s]=1;	
            qu.push(s);	
  		  }
		}	
		vis[e]=2;
  	  }
	  if(f[ST][1]){
  	    printf("N\n");
		ST-=m; dir=1;
  	  }
  	  else{
  	    printf("E\n");
		ST+=1; dir=2;
  	  }
  	  while(ST!=TR){
  	    if(f[ST][dir]){
    	  printf("F");
		  ST=getnext(ST,dir);  	
		  continue;
  	    }	
  	    int l=(dir+3)%4,r=(dir+5)%4;
  	    if(f[ST][l]){
    	  printf("L");
    	  dir=l;
		  ST=getnext(ST,l);  	
 	    }
 	    else{
    	  printf("R");
    	  dir=r;
		  ST=getnext(ST,r);  	
  	    }
  	  }
  	  printf("\n");
    }
	
	return 0;
}

其实码完才发现不用化图,本来化图是为了可能可以套什么模板,没想到直接可以做了。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值