题解 AT3875 [ARC089A] Traveling

Posted OI-Master

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解 AT3875 [ARC089A] Traveling相关的知识,希望对你有一定的参考价值。

不难发现,如果想要从 \\((x_i,y_i)\\) 走到 \\((x_{i+1},y_{i+1})\\),所需要的时间最少是 \\(|x_{i+1}-x_i|+|y_{i+1}-y_i|\\)
同时,走的时间是 \\(t_{i+1}-t_i\\)

那么初步判断,当距离大于时间,也就是说走最短路也没法按时走到,就一定不可能。

由此我们假设距离是 \\(dis\\),时间差是 \\(td\\),就可以写出以下代码:

if(dis>td){
	cout<<"No"<<endl;
	return 0;
}

接下来,我们考虑能走到的情况。正好走到的情况一定最好,但是如果多的话就不一定了。考虑简化问题,我们先让这个角色沿最短路走到 \\((x_{i+1},y_{i+1})\\)

然后根据题目所说,当现在位置是 \\((x,y)\\),一次可以走到 \\((x+1,y)\\)\\((x-1,y)\\)。那么我们不停让此角色左右反复弹跳不就是了?

形象点,当我们走到 \\((x_{i+1},y_{i+1})\\) 时,如果有多余时间我们就往右走,然后下一步走回来,不停循环。

那么多余的时间求法就是用 \\(td-dis\\)。我们注意到,当多余的时间是偶数时,我们可以反复弹跳若干次后回来。不过当多余的时间是奇数时,我们在某次弹到右边就回不来了。

所以,可以写出一下判断代码(这里假设多余的时间还是叫做 \\(td\\)

if(td%2==1){
	cout<<"No"<<endl;
	return 0;
}

完整代码:

#include<iostream>
#include<cmath>
using namespace std;
int main(){
	int n;
	cin>>n;
	int t[n+1];
	int x[n+1];
	int y[n+1];
	x[0]=y[0]=t[0]=0;
	for(int i=1;i<=n;++i)
		cin>>t[i]>>x[i]>>y[i];
	for(int i=1;i<=n;++i){
		int dis=abs(x[i]-x[i-1])+abs(y[i]-y[i-1]);
		int td=t[i]-t[i-1];
		if(dis>td){
			cout<<"No"<<endl;
			return 0;
		}
		td-=dis;
		if(td%2==1){
			cout<<"No"<<endl;
			return 0;
		}
	}
	cout<<"Yes"<<endl;
}

AC记录:https://www.luogu.com.cn/record/51672719,请指挥使放心审核!

以上是关于题解 AT3875 [ARC089A] Traveling的主要内容,如果未能解决你的问题,请参考以下文章

AT2272 [ARC066B] Xor Sum 题解

AT2272 [ARC066B] Xor Sum 题解

BZOJ3875: [Ahoi2014&Jsoi2014]骑士游戏

[Arc068D/At2299] Card Eater - 结论

AT4108 [ARC094D] Normalization

AT2395 [ARC071C] TrBBnsformBBtion(构造)