hdu 2012 A计划

7 篇文章 0 订阅
3 篇文章 0 订阅

该题是典型的bfs 和队列的结合~~~

#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
struct node
{
	int x,y,k;
	int time;
	friend bool operator<(node a,node b)  //优先队列   a小的优先级高 
	{
		return a.time>b.time;
	}
};
 


int biaoji[20][20][2];
int n,m,mox,moy,mok,ti,shix,shiy,shik;
char a[20][20],b[20][20];   //两层楼的情况 
int dd[4][2]={0,1,1,0,-1,0,0,-1};  //逆时针方向 
 


int judge(int x,int y,int k)  //判断是否越界 或是 墙 
{
	if(x>=0&&x<n&&y>=0&&y<m)
	{
		if(k==0&&a[x][y]!='*')
		return 1;
		if(k==1&&b[x][y]!='*')
		return 1;
	}
return 0;
}


 
int dfs(int shix,int shiy,int shik)
{
	priority_queue<node>q;   //优先队列q
	node cur,next;
	int i,x,y,k;
	cur.x=shix;cur.y=shiy;  //当前的坐标
	cur.k=shik;cur.time=0;
	biaoji[shix][shiy][shik]=1;
	q.push(cur);   //当前坐标入队列
	while(!q.empty())
	{
		next=q.top();
		q.pop();
		if(next.x==mox&&next.y==moy&&next.k==mok)  //位置和层数都在公主坐标处 
		return next.time;
		if(next.time>=ti)
		return -100;
		for(i=0;i<4;i++)   //四个方向搜索 
		{
			x=next.x+dd[i][0];
			y=next.y+dd[i][1];
			k=next.k;
			if(judge(x,y,k)&&biaoji[x][y][k]==0)  //判断是否越界 
			{
				if(k==0&&a[x][y]=='#')  //原先在第一层且 下一个位置是时光机 
				{
					cur.time=next.time+1;
					cur.k=1;
					cur.x=x;cur.y=y;
					q.push(cur);
					biaoji[x][y][1]=1;
					continue;
				}
				if(k==1&&b[x][y]=='#')
				{
					cur.time=next.time+1;
					cur.k=0;
					cur.x=x;cur.y=y;
					q.push(cur);
					biaoji[x][y][0]=1;
					continue;
				}
				cur.time=next.time+1;
				cur.k=next.k;
				cur.x=x;cur.y=y;
				biaoji[x][y][k]=1;
				q.push(cur);
			}
			
		}
		
	} 
	return -100;
}
int main()
{
	int T,i,j;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d%d",&n,&m,&ti);
		memset(biaoji,0,sizeof(biaoji));
		
		for(i=0;i<n;i++)
		scanf("%s",a[i]);
		for(i=0;i<n;i++)
		scanf("%s",b[i]);
		
		for(i=0;i<n;i++)
		for(j=0;j<m;j++)   //保证不被撞死 
		{
			if(a[i][j]=='#'&&b[i][j]=='#')
			{
				a[i][j]='*';b[i][j]='*';
			}
			
			if(a[i][j]=='#'&&b[i][j]=='*')
			a[i][j]='*';
			
			if(a[i][j]=='*'&&b[i][j]=='#')
			b[i][j]='*';
		}
		
		
		for(i=0;i<n;i++)
		for(j=0;j<m;j++)   //判断哪里是起始点 哪里是终点 
		{
			if(a[i][j]=='P')
			{
				mox=i;moy=j;mok=0;
			}
			if(b[i][j]=='P')
			{
				mox=i;moy=j;mok=1;
			}
			if(a[i][j]=='S')
			{
				shix=i;shiy=j;shik=0;
			}
			if(b[i][j]=='S')
			{
				shix=i;shiy=j;shik=1;
			}
		}
		int ans;
		ans=dfs(shix,shiy,shik);
		if(ans<=ti&&ans!=-100)
		printf("YES\n");
		else
		printf("NO\n");
	}
return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值