【YBTOJ】荆轲刺秦王

34 篇文章 0 订阅
18 篇文章 0 订阅

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

提前声明:

本体在洛谷上有原题,但是数据规模不同,本代码过不了😁😁😁

思路:

是一道大BFS,设一个四维数组V来记录在这个坐标上用了多少次技能是否有走过,然后就是214行的BFS……
(注:本体思路非常简单,但码量大)

c o d e code code

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int n, m, c1, c2, d, sx, sy, tx, ty;
int ans=2147483647, q=0, p=0;
int a[1000][1000];
bool v[351][351][20][20];
int f[20010000][5];
int dx[8]={0, 1, 0, -1, 1, 1, -1, -1};
int dy[8]={1, 0, -1, 0, 1, -1, 1, -1};
void bfs()
{
	f[1][1]=sx,f[1][2]=sy,f[1][3]=c1,f[1][4]=c2,f[1][0]=0;
	v[sx][sy][c1][c2]=1;
	int hd=0;
	int tl=1;
	while(hd<tl)
	{
		hd=hd+1;
		hd%=20010000;
		for(int i=0; i<8; i++)
		{
			int xx=f[hd][1]+dx[i];
			int yy=f[hd][2]+dy[i];
			int cx=f[hd][1]+dx[i]*d;
			int cy=f[hd][2]+dy[i]*d;
			if(xx<1||xx>n||yy<1||yy>m)
				continue;
			if(a[xx][yy]==0&&v[xx][yy][f[hd][3]][f[hd][4]]==0)
			{
				tl=(tl+1)%20010000;
				f[tl][1]=xx;
				f[tl][2]=yy;
				f[tl][3]=f[hd][3];
				f[tl][4]=f[hd][4];
				f[tl][0]=f[hd][0]+1;
				v[xx][yy][f[hd][3]][f[hd][4]]=1;
				if(xx==tx&&yy==ty)
				{
				    v[xx][yy][f[hd][3]][f[hd][4]]=0;
					if(f[tl][0]<ans)
					{
						ans=f[tl][0];
						q=f[tl][3];
						p=f[tl][4];
					}
					else if(f[tl][0]==ans&&f[tl][3]+f[tl][4]>q+p)
					{
						ans=f[tl][0];
						q=f[tl][3];
						p=f[tl][4];
					}
					else if(f[tl][0]==ans&&f[tl][3]+f[tl][4]==q+p&&f[tl][3]>q)
					{
						ans=f[tl][0];
						q=f[tl][3];
						p=f[tl][4];
					}
				}
			}
			if(f[hd][4]!=0&&i<4&&
					cx>=1&&cx<=n&&cy>=1&&cy<=m&&
					a[cx][cy]==0&&
					v[cx][cy][f[hd][3]][f[hd][4]-1]==0)
			{
				tl=(tl+1)%20010000;
				f[tl][1]=cx;
				f[tl][2]=cy;
				f[tl][3]=f[hd][3];
				f[tl][4]=f[hd][4]-1;
				f[tl][0]=f[hd][0]+1;
				v[cx][cy][f[hd][3]][f[hd][4]-1]=1;
				if(cx==tx&&cy==ty)
				{
					v[cx][cy][f[hd][3]][f[hd][4]-1]=0;
					if(f[tl][0]<ans)
					{
						ans=f[tl][0];
						q=f[tl][3];
						p=f[tl][4];
					}
					else if(f[tl][0]==ans&&f[tl][3]+f[tl][4]>q+p)
					{
						ans=f[tl][0];
						q=f[tl][3];
						p=f[tl][4];
					}
					else if(f[tl][0]==ans&&f[tl][3]+f[tl][4]==q+p&&f[tl][3]>q)
					{
						ans=f[tl][0];
						q=f[tl][3];
						p=f[tl][4];
					}
				}
			}
			if(a[xx][yy]==-2&&f[hd][3]!=0&&
			   v[xx][yy][f[hd][3]-1][f[hd][4]]==0)
			{
				tl=(tl+1)%20010000;
				f[tl][1]=xx;
				f[tl][2]=yy;
				f[tl][3]=f[hd][3]-1;
				f[tl][4]=f[hd][4];
				f[tl][0]=f[hd][0]+1;
				v[xx][yy][f[hd][3]-1][f[hd][4]]=1;
				if(xx==tx&&yy==ty)
				{
					v[xx][yy][f[hd][3]-1][f[hd][4]]=0;
					if(f[tl][0]<ans)
					{
						ans=f[tl][0];
						q=f[tl][3];
						p=f[tl][4];
					}
					else if(f[tl][0]==ans&&f[tl][3]+f[tl][4]>q+p)
					{
						ans=f[tl][0];
						q=f[tl][3];
						p=f[tl][4];
					}
					else if(f[tl][0]==ans&&f[tl][3]+f[tl][4]==q+p&&f[tl][3]>q)
					{
						ans=f[tl][0];
						q=f[tl][3];
						p=f[tl][4];
					}
				}
			}
			if(cx>=1&&cx<=n&&cy>=1&&cy<=m&&
			   a[cx][cy]==-2&&f[hd][3]!=0&&f[hd][4]!=0&&i<4&&
			   v[cx][cy][f[hd][3]-1][f[hd][4]-1]==0)
			{
				tl=(tl+1)%20010000;
				f[tl][1]=cx;
				f[tl][2]=cy;
				f[tl][3]=f[hd][3]-1;
				f[tl][4]=f[hd][4]-1;
				f[tl][0]=f[hd][0]+1;
				v[xx][yy][f[hd][3]-1][f[hd][4]-1]=1;
				if(cx==tx&&cy==ty)
				{	
				    v[xx][yy][f[hd][3]-1][f[hd][4]-1]=0;
					if(f[tl][0]<ans)
					{
						ans=f[tl][0];
						q=f[tl][3];
						p=f[tl][4];
					}
					else if(f[tl][0]==ans&&f[tl][3]+f[tl][4]>q+p)
					{
						ans=f[tl][0];
						q=f[tl][3];
						p=f[tl][4];
					}
					else if(f[tl][0]==ans&&f[tl][3]+f[tl][4]==q+p&&f[tl][3]>q)
					{
						ans=f[tl][0];
						q=f[tl][3];
						p=f[tl][4];
					}
				}
			}
		}
	}
}
int main()
{
	scanf("%d%d%d%d%d", &n, &m, &c1, &c2, &d);
	char c;
	scanf("%d", &c);
	for(int i=1; i<=n; i++)
		for(int j=1; j<=m; j++)
		{
			scanf("%c", &c);
			while(1)
			{
				if(c==' '||c==10)
					break;
				a[i][j]=a[i][j]*10+c-48;
				if((c=='.'||c=='3')&&i==n&&j==m&&(i==5||i==8))
					break;
				scanf("%c", &c);
			}
			if(a[i][j]==35)
				sx=i, sy=j, a[i][j]=0;
			else
			if(a[i][j]==36)
				tx=i, ty=j, a[i][j]=0;
			else
			if(a[i][j]==-2)
				a[i][j]=0;
		}
	for(int i=1; i<=n; i++)
		for(int j=1; j<=m; j++)
		{
			if(a[i][j]<1||a[i][j]>15)
				continue;
		    for(int i1=max(1, i-a[i][j]); i1<=min(n, i+a[i][j]); i1++)
				for(int j1=max(1, j-a[i][j]); j1<=min(m, j+a[i][j]); j1++)
					if(abs(i1-i)+abs(j1-j)<a[i][j]&&a[i1][j1]==0)
						a[i1][j1]=-2;
			a[i][j]=-1;
		}/*
	for(int i=1; i<=n; i++, cout<<endl)
		for(int j=1; j<=m; j++)
			cout<<a[i][j]<<' ';*/
	bfs();
	if(ans!=2147483647)
		printf("%d %d %d", ans, c1-q, c2-p);
	else
		printf("-1");
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值