問題の説明
「飛ぶ鳥は、」人気のあるゲームです。ゲームでは、鳥が起動が(0,0)に位置しており、その目標は、上の位置Xのために横軸に飛ぶことです。毎秒、あなたはその後、鳥は(x、y)は(X + 1、Y + 1)から飛行する、またはをクリックしていない、そして鳥は、X + 1(Y-1を飛ぶ、画面をクリックして選択することができます)。
障害の数、ゲームに記載のトリプル(X [i]は、[I]、B [i])とがあり、N、直線を表し、X = X [i]はA、Y <= [I]またはy> = B [i]には、障害物の一部であるヒットゲーム又は失敗放牧と考えられます。少なくともどのように多くの画面上でクリックする必要が先に飛ぶように(0,0)から鳥を要求します。
入力形式
最初の行は二つの整数N(0 <= N <= 500000)、Xを含有する(1 <= X <= 10 ^ 9)。
次のn行、各行三つの整数をx [i]は、[I]、B [i]は(0 <X [i]の<X、-10 ^ 9 <= [I] <B [i]は< ^ 9 = 10)。データ保証は、x [i]は<X [I + 1]。
出力フォーマット
いずれの場合も、先にそうでなければ、出力画面出力NIE、クリック数の最小値を飛ぶしない場合。
解決
私たちのように記録された、すべての障害物を越える高さを決定したと仮定(H_1、H_2、H3、......、h_n \)\、その後のIとI-1番目の障害物に注意してください。点の数が間にある\(X_I \) 、点の数ではない\(Y_I \) 、その後、我々は
[X_I + Y_I = dis_i- \ dis_ {I-1} \\ X_I-Y_I = H_I-H_ {I -1} \]
方程式を解くことにより、我々は入手
\ [X_I = \ FRAC {dis_i
-dis_ {I-1} + H_I-H_ {I-1} {2} \] 全て\(X_Iが\)追加したものです我々の答えはのために、ある
\ [\ sum_ {i = 1
} ^ {n}はX_I = \ FRAC {dis_n + h_n} {2} \] ので、我々は唯一のメイクへの最終的な障害物に到達する必要がある場合に最小の高さ、すなわちことができます。質問は、プロセスが正当なものであることを確実にする方法です。私たちは、不法な状況が発生する可能性がありますかどうかを確認するために、各障害物コースを通して道、高度の上限と下限を再帰することができます。
注意を払う必要がある上限と下限の再帰、。我々がダウンしている場合は、それが下限障壁より低くてもよいし、我々は戻っ下限に数回クリックする必要があります。しかし、各時点で、最終的に高さが2増加するだろう、我々はまだ高さを取得し、するには、下の方法を検討する必要があります\([i]が1 \ ) 正しい下限を取得するために、パリティの違い。上限は同じ理由です。
コード
#include <iostream>
#include <cstdio>
#define N 500002
using namespace std;
int n,d,i,x[N],a[N],b[N],down,up;
int read()
{
char c=getchar();
int w=0,f=1;
while(c<'0'||c>'9'){
if(c=='-') f=-1;
c=getchar();
}
while(c<='9'&&c>='0'){
w=w*10+c-'0';
c=getchar();
}
return w*f;
}
int main()
{
n=read();d=read();
for(i=1;i<=n;i++) x[i]=read(),a[i]=read(),b[i]=read();
for(i=1;i<=n;i++){
int dis=x[i]-x[i-1];
if(down-dis>=a[i]+1) down-=dis;
else{
if((a[i]+1-down+dis)%2==0) down=a[i]+1;
else down=a[i]+2;
}
if(up+dis<=b[i]-1) up+=dis;
else{
if((up+dis-b[i]+1)%2==0) up=b[i]-1;
else up=b[i]-2;
}
if(down>up){
puts("NIE");
return 0;
}
}
int ans=(x[n]+down)/2;
printf("%d\n",ans);
return 0;
}