poj3083

这道题目结合了深搜和广搜,利用深搜求得最左边走和最右边走的个数,利用广搜求得最短路径,这里注意三个问题:

1)深搜时要把握方向,每一次都有一个面朝向(共有四种朝向),每一种朝向向左走和向右走的顺序都不一样,但要注意每种朝向都是最后走与该朝向背向的方向。

2)注意深搜时方向一定不要写错,否则可能会TLE

3)注意广搜时要剪枝,否则也会TLE

下面是代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <queue>
using namespace std;
#define Max 50
bool flag[Max][Max];
bool trag[Max][Max];
int Case;
int w,h;
int Llen,Rlen;
int startx,starty,endx,endy;
char start_dir;
typedef struct Node{
	int x;
	int y;
	int deep;
}node;
void Ldfs(char dir,int x,int y,int deep){
	if(x==endx && y==endy){
		Llen=deep;
		return ;
	}
	switch(dir){
case 'N':
		if(y-1>=1 && flag[x][y-1])
			Ldfs('W',x,y-1,deep+1);
		else if(x-1>=1 && flag[x-1][y])
			Ldfs('N',x-1,y,deep+1);
		else if(y+1<=w && flag[x][y+1])
			Ldfs('E',x,y+1,deep+1);
		else
			Ldfs('S',x+1,y,deep+1);
		break;
case 'S':
		if(y+1<=w && flag[x][y+1])
			Ldfs('E',x,y+1,deep+1);
		else if(x+1<=h && flag[x+1][y])
			Ldfs('S',x+1,y,deep+1);
		else if(y-1>=1 && flag[x][y-1])
	        Ldfs('W',x,y-1,deep+1);
		else
			Ldfs('N',x-1,y,deep+1);
		break;
case 'W':
	    if(x+1<=h && flag[x+1][y])
			Ldfs('S',x+1,y,deep+1);
	    else if(y-1>=1 && flag[x][y-1])
	        Ldfs('W',x,y-1,deep+1);
		else if(x-1>=1 && flag[x-1][y])
		    Ldfs('N',x-1,y,deep+1);
		else
			Ldfs('E',x,y+1,deep+1);
		break;
default:
	    if(x-1>=1 && flag[x-1][y])
			Ldfs('N',x-1,y,deep+1);
		else if(y+1<=w && flag[x][y+1])
			Ldfs('E',x,y+1,deep+1);
		else if(x+1<=h && flag[x+1][y])
			Ldfs('S',x+1,y,deep+1);
		else
			Ldfs('W',x,y-1,deep+1);
		break;
	}
}
void Rdfs(char dir,int x,int y,int deep){
	if(x==endx && y==endy){
		Rlen=deep;
		return ;
	}
	switch(dir){
case 'N':
	    if(y+1<=w && flag[x][y+1])
			Rdfs('E',x,y+1,deep+1);
		else if(x-1>=1 && flag[x-1][y])
			Rdfs('N',x-1,y,deep+1);
	
		else if(y-1>=1 && flag[x][y-1])
			Rdfs('W',x,y-1,deep+1);
		
		else
			Rdfs('S',x+1,y,deep+1);
	
		break;
case 'S':
	    if(y-1>=1 && flag[x][y-1])
	        Rdfs('W',x,y-1,deep+1);
		else if(x+1>=1 && flag[x+1][y])
		    Rdfs('S',x+1,y,deep+1);
		else if(y+1<=w && flag[x][y+1])
			Rdfs('E',x,y+1,deep+1);
		else
			Rdfs('N',x-1,y,deep+1);
		break;
case 'W':
	    if(x-1>=1 && flag[x-1][y])
		    Rdfs('N',x-1,y,deep+1);
		
	    else if(y-1>=1 && flag[x][y-1])
	        Rdfs('W',x,y-1,deep+1);
		
		else if(x+1<=h && flag[x+1][y])
			Rdfs('S',x+1,y,deep+1);
		
		else
			Rdfs('E',x,y+1,deep+1);
	
		break;
default:
	    if(x+1<=h && flag[x+1][y])
			Rdfs('S',x+1,y,deep+1);
		
		else if(y+1<=w && flag[x][y+1])
			Rdfs('E',x,y+1,deep+1);
		
		else if(x-1>=1 && flag[x-1][y])
			Rdfs('N',x-1,y,deep+1);
		
		else
			Rdfs('W',x,y-1,deep+1);
		break;
	}
}
	
int bfs(){
	//int count=1;
	memset(trag,0,sizeof(trag));
	queue<node> Queue;
	node Point;
	Point.x=startx;
	Point.y=starty;
	Point.deep=1;
	Queue.push(Point);
	trag[startx][starty]=1;
	int x,y,count;
	while(!Queue.empty()){
		Point = Queue.front();
		Queue.pop();
		if(Point.x==endx && Point.y==endy)
			return Point.deep;
		x=Point.x,y=Point.y;
		count=Point.deep;
		if(x-1>=1 && flag[x-1][y] && !trag[x-1][y]){
			Point.x=x-1;
			Point.y=y;
			Point.deep=count+1;
			trag[x-1][y]=1;
			Queue.push(Point);
		}
		if(x+1<=h && flag[x+1][y] && !trag[x+1][y]){
			Point.x=x+1;
			Point.y=y;
			Point.deep=count+1;
			trag[x+1][y]=1;
			Queue.push(Point);
		}
		if(y-1>=1 && flag[x][y-1] && !trag[x][y-1]){
			Point.x=x;
			Point.y=y-1;
			Point.deep=count+1;
			trag[x][y-1]=1;
			Queue.push(Point);
		}
		if(y+1<=w && flag[x][y+1] && !trag[x][y+1]){
			Point.x=x;
			Point.y=y+1;
			Point.deep=count+1;
			trag[x][y+1]=1;
			Queue.push(Point);
		}
	}
}


int main(){
  scanf("%d",&Case);
  while(Case--){
	  scanf("%d%d",&w,&h);
	  memset(flag,0,sizeof(flag));
	  char temp;
	  for(int i=1;i<=h;i++){
		  getchar();
		  for(int j=1;j<=w;j++){
			  temp=getchar();
			  if(temp=='.')
				  flag[i][j]=1;
			  else if(temp=='S'){
				  if(i==1)
					  start_dir='S';
				  else if(i==h)
					  start_dir='N';
				  else if(j==1)
					  start_dir='E';
				  else if(j==w)
					  start_dir='W';
				  startx=i;
				  starty=j;
			  }
			  else if(temp=='E'){
				  endx=i;
				  endy=j;
				  flag[i][j]=1;
			  }
		  }
	  }
	  //printf("%d %d\n",startx,starty);
      Ldfs(start_dir,startx,starty,1);
	  //printf("%d\n",Llen);
      Rdfs(start_dir,startx,starty,1);
	  printf("%d %d %d\n",Llen,Rlen,bfs());
  }
  return 0;
}
	
  
  
  
  
  


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值