POJ2251

坑爹的是竟然把这题目分类在了深搜里面。

昨天做到POJ3009,也是把题目放在深搜里面。然后求最短路,自己就用BFS做,结果TLE了。就采用DFS做了。

今天这题又放在DFS里面,以为用BFS会TLE。结果用DFS搜索所有路径找最短路才是TLE的。晕啊,看来还是不要轻易的相信题目的分类。

先贴一下TLE的DFS代码,直接以步数深搜和当前坐标点下去就OK了。

#include<stdio.h>
#include<iostream>
#include<cstring>
#define INF 30000
using namespace std;
const int Arsize=30;
int Maps[Arsize][Arsize][Arsize];
int vis[Arsize][Arsize][Arsize];
int dx[]={-1,1,0,0,0,0};
int dy[]={0,0,-1,1,0,0};
int level[]={0,0,0,0,1,-1};
int L,R,C,endx,endy,end_level,startx,starty,start_level;
int min_minute;
void dfs(int time,int x,int y,int l){
	int i,move_x,move_y,move_level;
	if(x==endx&&y==endy&&l==end_level){
		if(time<min_minute){
			min_minute=time;
			return ;
		}
	}
	for(i=0;i<6;i++){
		move_x=x;
		move_y=y;
		move_level=l;
		move_x+=dx[i];
		move_y+=dy[i];
		move_level+=level[i];
		if(move_x>=0&&move_x<R&&move_y>=0&&move_y<C&&move_level>=0&&move_level<L){
	    	if(!Maps[move_level][move_x][move_y]&&!vis[move_level][move_x][move_y]){
		    	vis[move_level][move_x][move_y]=1;
		    	dfs(time+1,move_x,move_y,move_level);
		    	vis[move_level][move_x][move_y]=0;
	    	}
    	}
	}
}
int main()
{
	int i,j,k;
	char str[31];
	while(scanf("%d%d%d",&L,&R,&C)!=EOF){
		if(!L&&!R&&!C)
			break;
		memset(Maps,0,sizeof(Maps));
		memset(vis,0,sizeof(vis));
		min_minute=INF;
		for(i=0;i<L;i++){
			getchar();
			for(j=0;j<R;j++){
				fgets(str,31,stdin);
				for(k=0;k<C;k++){
					if(str[k]=='#'){
						Maps[i][j][k]=1;
					}
					else{
						Maps[i][j][k]=0;
						if(str[k]=='S'){
							start_level=i;
							startx=j;
							starty=k;
						}
						if(str[k]=='E'){
							end_level=i;
							endx=j;
							endy=k;
						}
					}
				}
			}
		}
		vis[start_level][startx][starty]=1;
		dfs(0,startx,starty,start_level);
		if(min_minute==INF){
			cout << "Trapped!\n";
		}
		else
			cout << "Escaped in " << min_minute << " minute(s).\n";
		cin.get();
	}
	return 0;
}

后面重新写了一下广搜的代码。最近深搜题目做多了,终于不用再在网上找解题报告参考思路写了,自己也能A掉几个水题了,呵呵。

下面就是采用广搜的形式。一开始老RE,结果发现hash函数返回返错了,倒。

发现就是一个很简单的判重,直接用vis数组就可以解决,后面就改了一下。

AC代码 :0MS

#include<iostream>
#include<cstring>
using namespace std;
const int Arsize=31;
const int Max=27001;
struct Node{
	int x,y,level;
	int dist;
};
Node path[Max];
int Maps[Arsize][Arsize][Arsize];
int vis[Arsize][Arsize][Arsize];
int dx[]={-1,1,0,0,0,0};
int dy[]={0,0,-1,1,0,0};
int level[]={0,0,0,0,-1,1};
int end_x,end_y,end_level,start_x,start_y,start_level;
int L,R,C;
int bfs(void){
	int i,rear=2,front=1,move_x,move_y,move_level;
	path[1].x=start_x;
	path[1].y=start_y;
	path[1].level=start_level;
	path[1].dist=0;
	vis[start_level][start_x][start_y]=1;
	while(front<rear){
		Node &now=path[front];
		if(now.x==end_x&&now.y==end_y&&now.level==end_level)
			return front;
		for(i=0;i<6;i++){
			move_x=now.x;
			move_y=now.y;
			move_level=now.level;
			move_x+=dx[i];
			move_y+=dy[i];
			move_level+=level[i];
			if(move_x>=0&&move_x<R&&move_y>=0&&move_y<C&&move_level>=0&&move_level<L){
				if(!Maps[move_level][move_x][move_y]&&!vis[move_level][move_x][move_y]){
					vis[move_level][move_x][move_y]=1;
			    	path[rear].x=move_x;
			    	path[rear].y=move_y;
			    	path[rear].level=move_level;
			    	path[rear].dist=now.dist+1;
					rear++;
				}
		 	}
		}
		front++;
	}
	return 0;
}
int main()
{
	int i,j,k,last;
	char str[31];
	while(cin >> L >> R >> C){
		if(!L&&!R&&!C)
			break;
		memset(Maps,0,sizeof(Maps));
		memset(vis,0,sizeof(vis));
		for(i=0;i<L;i++){
			cin.get();
			for(j=0;j<R;j++){
				cin.getline(str,31);
				for(k=0;k<C;k++){
					if(str[k]=='#'){
						Maps[i][j][k]=1;
					}
					else{
						Maps[i][j][k]=0;
						if(str[k]=='S'){
							start_level=i;
							start_x=j;
							start_y=k;
						}
						else if(str[k]=='E'){
							end_level=i;
							end_x=j;
							end_y=k;
						}
					}
				}
			}
		}
		last=bfs();
		if(last){
			cout << "Escaped in " << path[last].dist <<" minute(s).\n";
		}
		else
			cout << "Trapped!\n";
	}
	return 0;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值