题解 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的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ3875: [Ahoi2014&Jsoi2014]骑士游戏
[Arc068D/At2299] Card Eater - 结论