1. 程式人生 > >[思維]Flappy Bird

[思維]Flappy Bird

題目描述

《飛揚的小鳥》是一款風靡的小遊戲。在遊戲中,小鳥一開始位於(0,0)處,它的目標是飛到橫座標為X的某個位置上。每一秒,你可以選擇點選螢幕,那麼小鳥會從(x,y)飛到(x+1,y+1),或者不點選,那麼小鳥會飛到(x+1,y-1)。在遊戲中還有n個障礙物,用三元組(x[i],a[i],b[i])描述,表示在直線x=x[i]上,y<=a[i]或者y>=b[i]的部分都是障礙物,碰到或者擦邊都算遊戲失敗。請求出小鳥從(0,0)飛到目的地最少需要點選多少次螢幕。

 

輸入

第一行包含兩個整數n(0<=n<=500000),X(1<=n<=10^9)。
接下來n行,每行三個整數x[i],a[i],b[i](0<x[i]<X,-10^9<=a[i]<b[i]<=10^9)。
資料保證x[i]<x[i+1]。

 

輸出

如果無論如何都飛不到目的地,輸出NIE,否則輸出點選螢幕的最少次數。
 

 

樣例輸入

4 11
4 1 4
7 -1 2
8 -1 3
9 0 2

樣例輸出

5

 

提示

 

思路:

 

從圖中可以看出,從(0,0)出發,飛到直線x=xi上時,當xi為奇數,到達的點只可能是(xi,-3/-1/1/3/5/...),當xi為偶數時,到達的點只可能是(xi,-4/-2/0/2/4/6/...);因此,對每一個障礙物,維護其可以通過的最高點和最低點。

AC程式碼:

#include <iostream>
#include
<cstdio> #include<algorithm> typedef long long ll; using namespace std; ll x[500005],a[500005],b[500005]; int main() { ll n,X;scanf("%lld%lld",&n,&X); for(ll i=1;i<=n;i++){ scanf("%lld%lld%lld",&x[i],&a[i],&b[i]); a[i]++; b[i]--; } ll u
=0,d=0; for(ll i=1;i<=n;i++){ ll dis=x[i]-x[i-1]; u=min(u+dis,b[i]); d=max(d-dis,a[i]); if((u&1)!=(x[i]&1)) u--; if((d&1)!=(x[i]&1)) d++; if(u<d) {printf("NIE\n"); return 0;} } printf("%lld\n",x[n]-(x[n]-d)/2); return 0; }