トピック
問題951:感傷性の
時間制限:2000ミリ秒メモリ制限:128000 KB問題の説明
感傷的な10代のWSWはゼブラクロッシングを横切る必要があります。ゼブラクロッシングは、n個の交互に並んだ黒と白のストライプで構成され、最初のものは黒です。WSWピンの長さはsです。WSWは、歩行の過程で、彼の足のどの部分も悪を象徴する黒いバーに触れてはならないことを要求しています。最初の記事の前とn番目の記事の後の部分はすべて白であり、WSWは最初の記事の開始前に任意の位置を選択できます。ただし、開始位置を選択したら、WSWの各ステップの長さをkにする必要があります。WSWが黒いバーにぶつからないで、つまりn番目のバーの後にゼブラクロッシングを横切ることができるかどうかを判断してください。
入力
入力ファイルemotional.inには複数のデータセットがあります。
1行目の整数tは、データグループの数を表します。
各データグループの最初の行には、3つの整数s、k、nがあります。
2番目の行にはn個の整数A_1、A_2、…、A_nがあり、黒と白のバーの長さを表します。100%の
2<=n<=500000
データ、1<=s<k<=10^9
、1<=A_i<=10^9
、1<=t<=10
、。出力
データの各グループは1行を出力します。
出力「TAK」を渡すことができる場合は、「NIE」を出力します。入力例
6
3 9 10
3 3 3 1 1 3 2 1 2 13 13 5
3 2 1 3 33 12 8
1 1 3 3 2 2 1 13 9 6
3 3 1 1 3 12 8 7
2 5 6 3 2 1 22 8 4
1 6 7 4出力例
いいえ
はい
はい
はい
はい
いいえ
分析
- 線分は、0から始まり、数直線に近い線分と考えてください。
- 各ステップの長さは黒の領域ごとに固定されているため、すべての数値はinterval%kであり、interval
[0,k-1]
にマッピングされているため、これらのポイントの係数を表すことはできません(または確実に黒の領域に入ります)。最後に、[0,k-1]
その中に白い点(黒く染まっていない)があるかどうかを確認します。計画があるかどうかがわかります。
プログラム
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
struct zzk{ll l,r;} a[1000005]; //区间 l,r 不可行
bool cmp(zzk x,zzk y){
if (x.l==y.l) return x.r>y.r;
return x.l<y.l;
}
ll i,t,n,s,k,l,r,len,F,kl,kr,k1,k2,num,R;
void upd(ll x,ll y){
if (y<x){
return;}
kl=x/k,kr=y/k;
k1=x%k,k2=y%k;
if (y-x>=k){a[++num]=(zzk){
0,k-1}; return;}
if (kl==kr){
a[++num]=(zzk){k1,k2};
return;
}
if (kr-kl==1){
a[++num]=(zzk){k1,k-1};
a[++num]=(zzk){
0,k2};
return;
}
}
int main(){
for (scanf("%lld",&t),F=1; t--; F=1,num=0){
scanf("%lld%lld%lld",&s,&k,&n); //一步长 k,脚长 s
for (i=l=0; i<n && F; i++){
scanf("%lld",&len);
r=l+len,l+=1; //右端点在 [l,r] 都不行
if (~i&1) upd(l,r+s-1);
l=r;
}
sort(a+1,a+num+1,cmp);
if (a[1].l>0){
puts("TAK"); continue;}
for (i=1,F=0,R=0; i<=num && !F; i++){
if (a[i].l>R+1){F=1; continue;}
R=max(R,a[i].r);
while (i<num && a[i+1].l==a[i].l) i++;
}
if ((R<k-1) || F){
puts("TAK"); continue;}
puts("NIE");
}
}
促す
- うわー、テスト中に関数が渡され、intとして開かれると、WAはゼロにバーストします...