DFS+BFS

21 篇文章 0 订阅

题意:给出起点和终点,两个点都在边上,,且其余边都封好。

         给出左优先搜索的距离,,右优先搜索的距离,,最短距离。


思路:前一个答案是由左、向、或、后,这四个方向的顺序就一定能找得到终点。

           第二个答案类似

          最短距离直接广搜就可以(由于自己写的是否已访问过的标记记了,T了两次)


#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>

using namespace std;

char map[44][44];
int n,m;
int ans_left;
int ans_right;
int ans_closet;
bool vist[44][44];
int sx,sy;
int a[4][2]={{1,0},{0,-1},{-1,0},{0,1}};


struct my
{
	int x,y;
	int step;
};

bool in(int x,int y)
{
	return x>=0 && x<n && y>=0 && y<m;
}

void bfs()
{
	my cur;
	cur.x=sx;
	cur.y=sy;
	cur.step=1;
	memset(vist,false,sizeof(vist));
	vist[sx][sy]=true;
	queue<my> q;
	q.push(cur);
	while (!q.empty())
	{
		my d=q.front();
		//cout<<d.x<<' '<<d.y<<' '<<d.step<<endl;
		q.pop();
		if (map[d.x][d.y]=='E')
		{
			ans_closet=d.step;
			break;
		}
		for (int i=0;i<4;i++)
		{
			int x=d.x+a[i][0];
			int y=d.y+a[i][1];
			if (in(x,y) && !vist[x][y] && map[x][y]!='#')
			{
				cur.x=x;
				cur.y=y;
				vist[x][y]=true;
				cur.step=d.step+1;
				q.push(cur);
			}
		}
	}
}

int  isok(int x,int y)
{
	int sum=0;
	for (int i=0;i<4;i++)
	{
		int nextx=x+a[i][0];
		int nexty=y+a[i][1];
		if (!in(nextx,nexty) || map[nextx][nexty]=='#')
			sum++;
	}
	return sum;
}

void dfs_left(int x,int y,int step,int pre_dir)
{
	//cout<<x<<' '<<y<<endl;
	if (map[x][y]=='E')
	{
		ans_left=step;
		return;
	}
	int nextx,nexty;
	nextx=x+a[(3+pre_dir)%4][0];
	nexty=y+a[(3+pre_dir)%4][1];
	if (in(nextx,nexty)  && map[nextx][nexty]!='#')
	{
		dfs_left(nextx,nexty,step+1,(3+pre_dir)%4);
		return;
	}
	
	nextx=x+a[(pre_dir)%4][0];
	nexty=y+a[(pre_dir)%4][1];
	if (in(nextx,nexty)  && map[nextx][nexty]!='#')
	{
		dfs_left(nextx,nexty,step+1,(pre_dir)%4);
		return;
	}
	
	nextx=x+a[(1+pre_dir)%4][0];
	nexty=y+a[(1+pre_dir)%4][1];
	if (in(nextx,nexty)  && map[nextx][nexty]!='#')
	{
		dfs_left(nextx,nexty,step+1,(1+pre_dir)%4);
		return;
	}
	
	nextx=x+a[(2+pre_dir)%4][0];
	nexty=y+a[(2+pre_dir)%4][1];
	if (in(nextx,nexty) && map[nextx][nexty]!='#')
	{
		dfs_left(nextx,nexty,step+1,(2+pre_dir)%4);
		return;
	}
}

void dfs_right(int x,int y,int step,int pre_dir)
{
	//cout<<x<<' '<<y<<endl;
	if (map[x][y]=='E')
	{
		ans_right=step;
		return;
	}
	int nextx,nexty;
	nextx=x+a[(1+pre_dir)%4][0];
	nexty=y+a[(1+pre_dir)%4][1];
	if (in(nextx,nexty)  && map[nextx][nexty]!='#')
	{
		dfs_right(nextx,nexty,step+1,(1+pre_dir)%4);
		return;
	}
	
	nextx=x+a[(pre_dir)%4][0];
	nexty=y+a[(pre_dir)%4][1];
	if (in(nextx,nexty) && map[nextx][nexty]!='#')
	{
		dfs_right(nextx,nexty,step+1,(pre_dir)%4);
		return;
	}
	
	nextx=x+a[(3+pre_dir)%4][0];
	nexty=y+a[(3+pre_dir)%4][1];
	if (in(nextx,nexty)  && map[nextx][nexty]!='#')
	{
		dfs_right(nextx,nexty,step+1,(3+pre_dir)%4);
		return;
	}
	
	nextx=x+a[(2+pre_dir)%4][0];
	nexty=y+a[(2+pre_dir)%4][1];
	if (in(nextx,nexty) && map[nextx][nexty]!='#')
	{
		dfs_right(nextx,nexty,step+1,(2+pre_dir)%4);
		return;
	}
}



int main()
{
	freopen("in.txt","r",stdin);
	int i,j,k;
	int nc;
	cin>>nc;
	while (nc--)
	{
		scanf("%d%d",&m,&n);
		for (i=0;i<n;i++)
			scanf("%s",map[i]);
		for (i=0;i<n;i++)
		{
			for (j=0;j<m;j++)
			{
				
				if (map[i][j]=='S')
				{
					sx=i;
					sy=j;
				}
			}
		}
	
		bfs();
		dfs_left(sx,sy,1,0);
		dfs_right(sx,sy,1,0);
		printf("%d %d %d\n",ans_left,ans_right,ans_closet);
	}
	
	return 0;
}



1296


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值