题目大意:给定一个愤怒的小鸟,如果当前位置为 (x,y) ,按一下之后下一时刻会飞到 (x+1,y+1) ,否则会飞到 (x+1,y−1) ,求走到终点最少要按多少次
贪心
预处理
f[i]
表示第
i...n
个柱子中
a[i]−x[i]
的最大值,显然如果我在穿过第
i−1
个柱子后的某一时刻
y−x<=f[i]
,那么我就GG了
所以我先下降到这条线上方,然后再一直点就好了。
时间复杂度
O(n)
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 500500
using namespace std;
int n,X;
struct abcd{
int x,a,b,limit;
void Input()
{
scanf("%d%d%d",&x,&a,&b);
a++;b--;
limit = a-x;
if(limit&1) ++limit;
}
}a[M];
int main()
{
int ans=0;
cin>>n>>X;
for(int i=1;i<=n;i++)
a[i].Input();
for(int i=n-1;i>0;i--)
a[i].limit = max(a[i].limit , a[i+1].limit);
int x=0,y=0;
for(int i=1;i<=n;i++)
{
int temp=(y-x)-a[i].limit>>1;
if(temp<0) temp=0;
temp=a[i].x-x-temp;
if(temp<0) temp=0;
y+=temp;y-=a[i].x-x-temp;
x=a[i].x;
//cout<<x<<' '<<y<<endl;
if(y<a[i].a || y>a[i].b)
return cout<<"NIE"<<endl,0;
ans+=temp;
}
cout<<ans<<endl;
return 0;
}