poj3083 Children of the Candy Corn

比较简单的搜索题,用到了dfs和bfs。dfs比较适合搜索有无可行解,如本题中左转优先和右转优先是利用dfs算法求解得,而bfs适合寻找最优解,如本题最短路径就是bfs。

这道题有一个比较需要注意的地方就是bfs时用visit[][]记录是否访问时,一定要在加入que队列的时候就修改visit[x][y]的值,我第一次是在出队列的时候修改其值,因为想的是出队列时才是访问它的时候,但是这样就大错特错了!!RE了好久,真是伤不起。。。一定要在加入que时就修改visit!!

下面贴代码。

#include<iostream>
using namespace std;

char maze[41][41];
int nextmove[4][2]={0,1,1,0,0,-1,-1,0};			//方向分别是东、南、西、北
int lcount,rcount;
char visit[41][41];

void left(int x,int y,int dir,int w,int h){
	lcount++;
	if (maze[x][y]=='E') return;
	int ndir,nx,ny;
	for (int i=3;i<=6;i++){			//左转和右转先后次序是不一样的!
		ndir=(dir+i)%4;
		nx=x+nextmove[(dir+i)%4][0];
		ny=y+nextmove[(dir+i)%4][1];
		if (nx>=0 &&nx<h&&ny>=0&&ny<w&&maze[nx][ny]!='#') {break;}
	}
	left(nx,ny,ndir,w,h);
}
void right(int x,int y,int dir,int w,int h){
	rcount++;
	if (maze[x][y]=='E') return;
	int ndir,nx,ny;
	for (int i=5;i>=2;i--){			//右转优先,注意和left函数中的区别!
		ndir=(dir+i)%4;
		nx=x+nextmove[(dir+i)%4][0];
		ny=y+nextmove[(dir+i)%4][1];
		if (nx>=0 &&nx<h&&ny>=0&&ny<w&&maze[nx][ny]!='#') {break;}
	}
	right(nx,ny,ndir,w,h);
}
int que[1650][2];
void shortBFS(int sx,int sy,int w,int h){
	int front=0,rear=0,step=0,flag=0;
	memset(visit,'0',sizeof(visit));
	que[rear][0]=sx;
	que[rear++][1]=sy;
	visit[sx][sy]='1';

	while(front<rear&&!flag){
		int tmp=rear;
		step++;
		while (front<tmp){
			int cx=que[front][0];
			int cy=que[front++][1];
			if (maze[cx][cy]=='E'){cout<<step<<endl;flag=1;break;}
			int nx,ny;
			for (int i=0;i<4;i++){
				nx=cx+nextmove[i][0];
				ny=cy+nextmove[i][1];
				if (nx>=0 &&nx<h&&ny>=0&&ny<w&&maze[nx][ny]!='#'&&visit[nx][ny]!='1') {
					que[rear][0]=nx;
					que[rear++][1]=ny;
					visit[nx][ny]='1';			//一定要在这里就修改visit!
				}
			}
		}
	}	
}
int main(){
	int cases;
	cin>>cases;
	while(cases--){
		lcount=rcount=0;
		int w,h;
		cin>>w>>h;
		memset(maze,' ',sizeof(maze));
		for (int i=0;i<h;i++){
			cin>>maze[i];
		}
		int lax=-1,lay=-1;
		for (int i=0;i<h;i++){
			for (int j=0;j<w;j++){
				if (maze[i][j]=='S'){
					lax=i;
					lay=j;
					break;
				}
			}
		}
		left(lax,lay,0,w,h);
		cout<<lcount<<" ";
		right(lax,lay,0,w,h);
		cout<<rcount<<" ";
		shortBFS(lax,lay,w,h);
	}
	return 0;
}

欢迎留言交流哈,还是菜鸟仍在学习中。。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值