荆轲刺秦王(bfs)

荆轲刺秦王

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

解题思路

这题为一道广搜
很多种情况
代码量大了点

AC代码

#include<cmath>
#include<cstdio>
#include<iostream>
using namespace std;
int n,m,c1,c2,d,ex,ey,answer1=100000,answer2=100000,answer3=100000,answer4=100000,b[400][400],z[400][400],c[400][400][20][20];
int dx[8]={-1,0,1,0,-1,1,1,-1};//特殊
int dy[8]={0,1,0,-1,1,1,-1,-1};
string s;
struct node
{
	int x,y,c1,c2,ans;
}p[10000005];
void fz(int ans,int c1,int c2)//赋值
{
	answer1=ans;
	answer2=c1;
	answer3=c2;
	answer4=c1+c2;
}
bool check(int x,int y)//判断
{
	return x>=1&&x<=n&&y>=1&&y<=m;
}
void bfs()//bfs
{
	int head=0,tail=1;
	while(head<tail)
	{
		head++;
		head%=10000000;
		int ox=p[head].x,oy=p[head].y,o1=p[head].c1,o2=p[head].c2,oans=p[head].ans;
		for(int i=0;i<8;i++)
		{
			int xx=ox+dx[i],yy=oy+dy[i];
			if(check(xx,yy)&&!z[xx][yy])//不用瞬移
			{
				if(b[xx][yy])
				{
					if(o1+1<=c1&&!c[xx][yy][o1+1][o2])
					{
						c[xx][yy][o1+1][o2]=1;
						p[++tail]=(node){xx,yy,o1+1,o2,oans+1};
						tail%=100000000;
						if(xx==ex&&yy==ey)
						{
							if(oans+1<answer1)fz(oans+1,o1+1,o2);
							else if(oans+1==answer1&&o1+1+o2<answer4)fz(oans+1,o1+1,o2);
							else if(oans+1==answer1&&o1+1+o2==answer4&&o1+1<answer2)fz(oans+1,o1+1,o2);
						}
					}
				}
				else
				{
					if(!c[xx][yy][o1][o2])
					{
						c[xx][yy][o1][o2]=1;
						p[++tail]=(node){xx,yy,o1,o2,oans+1};
						tail%=100000000;
						if(xx==ex&&yy==ey)
						{
							if(oans+1<answer1)fz(oans+1,o1,o2);
							else if(oans+1==answer1&&o1+o2<answer4)fz(oans+1,o1,o2);
							else if(oans+1==answer1&&o1+o2==answer4&&o1<answer2)fz(oans+1,o1,o2);
						}
					}
				}
			}
			if(o2+1<=c2&&i<4)//用瞬移
	 		{
	 			int xx=ox+dx[i]*d,yy=oy+dy[i]*d;
	 			if(check(xx,yy)&&!z[xx][yy])
	 			{
	 				if(b[xx][yy])
	 				{
	 					if(o1+1<=c1&&!c[xx][yy][o1+1][o2+1])
	 					{
	 						c[xx][yy][o1+1][o2+1]=1;
	 						p[++tail]=(node){xx,yy,o1+1,o2+1,oans+1};
	 						tail%=100000000;
	 						if(xx==ex&&yy==ey)
							{
								if(oans+1<answer1)fz(oans+1,o1+1,o2+1);
								else if(oans+1==answer1&&o1+1+o2+1<answer4)fz(oans+1,o1+1,o2+1);
								else if(oans+1==answer1&&o1+1+o2+1==answer4&&o1+1<answer2)fz(oans+1,o1+1,o2+1);
							}
						}
					}
					else
					{
						if(!c[xx][yy][o1][o2])
						{
							c[xx][yy][o1][o2+1]=1;
							p[++tail]=(node){xx,yy,o1,o2+1,oans+1}; 
							tail%=100000000;
							if(xx==ex&&yy==ey)
							{
								if(oans+1<answer1)fz(oans+1,o1,o2+1);
								else if(oans+1==answer1&&o1+o2+1<answer4)fz(oans+1,o1,o2+1);
								else if(oans+1==answer1&&o1+o2+1==answer4&&o1<answer2)fz(oans+1,o1,o2+1);
							}
						}
					}
				}
			 }
		}
	}
	return;
} 
int main()
{
	scanf("%d%d%d%d%d",&n,&m,&c1,&c2,&d);
	for(int i=1;i<=n;i++)//输入
	 for(int j=1;j<=m;j++)
	 {
	 	cin>>s;
	 	if(s[0]=='S')p[1]=(node){i,j,0,0},c[i][j][0][0]=1;
	 	else if(s[0]=='T')ex=i,ey=j;
	 	else if(s[0]!='.')//预处理
	 	{
	 		int len=s.size(),sum=0;
	 		z[i][j]=1;
			for(int k=0;k<len;k++)
			 sum=sum*10+s[k]-48;
	 		for(int x=max(1,i-sum);x<=min(n,i+sum);x++)
			 for(int y=max(1,j-sum);y<=min(m,j+sum);y++)
			  if(abs(i-x)+abs(j-y)<sum)
			   b[x][y]=1;   
		}
	 }
	bfs();
	if(answer1==100000)printf("-1");
	else printf("%d %d %d",answer1,answer2,answer3);
	return 0;
}

谢谢

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值