【JZOJ1320】拯救奶牛

本文介绍了一种解决三角形迷宫逃脱问题的算法。贝希被困在一个由N行组成的三角形迷宫中,需要找到从任意位置到迷宫出口的最短路径。通过将原三角形分解为三个方向的三角形,利用绝对值距离之和来计算最优路径。文章详细解释了算法原理,包括如何定义迷宫结构、如何计算路径长度以及如何确定最佳出口。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

description

贝希被困在一个三角形的迷宫之中。这个迷宫有N行(1 <= N <= 1000000)。比如下图是一个3行的迷宫。


  
  迷宫的第i行有2*i-1个三角形,从左到右分别编号为(i,1)、(i,2)等等。贝希每次可以从一个三角形走到任意一个一个跟当前的三角形有邻边的三角形。比如说,如果她目前处于三角形(3,3),那么,她可以走到三角形(3,2)、(3,4)和(4,4)。贝希每次需要一分钟的时间来移动到下一个三角形。

农夫约翰发现贝希被困了!于是她跟踪贝希的iPhone手机(可怜的触摸屏~),得知贝希目前处于三角形(Si,Sj)。因为约翰对贝希有着无穷无尽的浓浓爱意,所以他希望贝希能尽可能快地回到他的身边。
  在迷宫的三角形之中,有M(1 <= M <= 10000)个是出口。在任何一个出口都可以让贝希逃离迷宫。一旦贝希进入一个作为出口的三角形,她用多一分钟就可以逃离这个迷宫。
  找到一个可以让贝希逃离迷宫最小时间T,并输出她应该从哪一个出口逃离迷宫,这个出口记为(OUTi,OUTj)。如果有多个出口同时需要时间T,输出那个行的编号小的出口,如果仍然有多个出口,输出那个列的编号小的。


analysis

  • 把原三角形旋转一下,看成三个三角形,顶部分别是原三角形最上、最左下和最右下的三个小三角

  • 对于原三角形的侧着走,相当于在另两个三角形中的横着走

  • 那么记录一个点分别在三个三角形中的行数,最小步数即为三个绝对值的和


code

#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAXN 10005
#define INF 1000000007
#define ll long long
#define reg register ll
#define fo(i,a,b) for (reg i=a;i<=b;++i)
#define fd(i,a,b) for (reg i=a;i>=b;--i)
#define O3 __attribute__((optimize("-O3")))

using namespace std;

ll n,begx,begy,begz,ans=INF,where;

struct node
{
	ll x,y,z,x1,y1;
}a[MAXN];

O3 inline ll read()
{
	ll x=0,f=1;char ch=getchar();
	while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
	while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
	return x*f;
}
O3 inline bool cmp(node a,node b)
{
	return a.x<b.x || ((a.x==b.x) && (a.y<b.y));
}
O3 int main()
{
	//freopen("T1.in","r",stdin);
	read(),n=read();
	ll x=read(),y=read();
	begx=x,begy=(y+1)/2,begz=x-y/2;
	fo(i,1,n)
	{
		ll x=read(),y=read();
		a[i].x=x,a[i].y=(y+1)/2,a[i].z=x-y/2;
		a[i].x1=x,a[i].y1=y;
	}
	sort(a+1,a+n+1,cmp);
	fo(i,1,n)
	{
		ll temp=abs(begx-a[i].x)+abs(begy-a[i].y)+abs(begz-a[i].z);
		if (temp<ans)ans=temp,where=i;
	}
	printf("%lld %lld\n%lld\n",a[where].x1,a[where].y1,ans+1);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值