题目大意:给定一个愤怒的小鸟,如果当前位置为(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;
}