hdu1728 逃离迷宫

题意:中文题。。。

解题思路:
        bfs,但要注意的是,一个点可能进队列不止一次,记录拐弯次数较少的进队列,相等的也进队列,
    如下例:
3 3
..*
...
*.*
1 1 1 3 2

还有个地方要注意的是:队列中的元素也要记录自己拐弯次数,不能直接用一个二维数组直接统计全部。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;

#define clr(p,v) memset(p,v,sizeof(p))
const int maxn = 110 ;
const int oo = 1<<30 ;

int n,m,T,k;
int st,en,x,y;
int num[maxn][maxn];  //总的最少拐弯次数
char s[maxn][maxn];
struct node
{
	int x,y,di,num;   //num统计该点最少拐弯次数
}kk,tt;
int dx[] = {0,-1,0,1};
int dy[] = {1,0,-1,0};

bool bfs()
{
	queue<node> q;
	clr(num,-1);
	//先处理相邻的四个点
	for(int i=0;i<4;i++)
	{
		int sx = x+dx[i], sy = y+dy[i];
		if(sx == st && sy == en) return true;
		if(sx>=0 && sy>=0 && sx<n && sy<m && s[sx][sy] == '.')
		{
			tt.x = sx; tt.y = sy; tt.di = i; tt.num = 0;
			q.push(tt);
			num[sx][sy] = 0;
		}
	}
	num[x][y] = k+1;
	while(!q.empty())
	{
		kk = q.front();
		q.pop();
		if(kk.x == st && kk.y == en) return true;
		for(int i=0;i<4;i++)
		{
			int sx = kk.x+dx[i], sy = kk.y+dy[i],uu = kk.num;
			if(sx>=0 && sy>=0 && sx<n && sy<m && s[sx][sy] == '.')
			{
				if(kk.di != i) uu++;
				if(uu > k) continue;
				if(sx == st && sy == en) return true;
				if(num[sx][sy]==-1 || uu<=num[sx][sy])
				{
					num[sx][sy] = uu;
					tt.x = sx; tt.y = sy; tt.di = i; tt.num = uu;
					q.push(tt);
				}
			}
		}
	}
	return false;
}

int main()
{
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d",&n,&m);
		for(int i=0;i<n;i++) scanf(" %s",s[i]);
		scanf("%d%d%d%d%d",&k,&y,&x,&en,&st);
		x--;y--;st--;en--;
		if((x==st && y==en) || bfs()) puts("yes");
		else puts("no");
	}
	return 0;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值