AtCoder Beginner Contest 245 C - Choose Elements
問題の要約
長さNの整数からなる数列A=(A1,...,AN),B=(B1,...,BN)が与えられる。
以下の条件を全て満たす長さNの数列X=(X1,...,XN)が存在するかを判定しろ。
・すべてのi(1<=i<=N)について、Xi=AiまたはXi=Bi
・すべてのi(1<=i<=N-1)について、|Xi-Xi+1|<=K (注)i+1は下付き文字
制約
1<=N<=2*10^5
0<=K<=10^9
1<=Ai,Bi<=10^9
入力
N K
A1 ... AN
B1 ... BN
考え方
1,条件の一つ目よりXi=AiまたはXi=Biなので,AiとBiだけ考慮に入れればよい。
2,|Xi-Xi+1|<=Kを考えるとき、
|Ai-Ai+1|<=Kまたは|Bi-Ai+1|ならばAi+1を考慮に入れる。
|Bi-Bi+1|<=Kまたは|Ai-Bi+1|ならばBi+1を考慮に入れる。
3,上の1と2をvector<int>で管理する。
0ならばAi+1,Bi+1どちらも該当なし。
1ならばAi+1だけ該当する。
2ならばBi+1だけ該当する。
3ならばAi+1,Bi+1どちらも該当する。
4,0からN-1までvector<int>に数値を入れていって0があればXは存在しない。そうでなければ存在する。
実際のプログラム
#include<iostream>
#include<vector>
using namespace std;
int main(){
long long N,K;
cin >> N >> K;
vector<long long> A(N);
for(long long i = 0; i < N; i++){
cin >> A[i];
}
vector<long long> B(N);
for(long long i = 0; i < N; i++){
cin >> B[i];
}
// 0 -> 該当なし
// 1 -> A該当
// 2 -> B該当
// 3 -> A,B該当
vector<int> check(N,0);
check[0] = 3;
bool ans = true;
for(long long i = 0; i < N; i++){
if(i == N-1){
if(check[i] == 0){
ans = false;
}
break;
}
if(check[i] == 0){
ans = false;
break;
}else if(check[i] == 1){
if(A[i] - A[i+1] <= K && A[i+1] - A[i] <= K){
check[i+1] += 1;
}
if(A[i] - B[i+1] <= K && B[i+1] - A[i] <= K){
check[i+1] += 2;
}
}else if(check[i] == 2){
if(B[i] - A[i+1] <= K && A[i+1] - B[i] <= K){
check[i+1] += 1;
}
if(B[i] - B[i+1] <= K && B[i+1] - B[i] <= K){
check[i+1] += 2;
}
}else if(check[i] == 3){
if(A[i] - A[i+1] <= K && A[i+1] - A[i] <= K){
check[i+1] += 1;
}else if(B[i] - A[i+1] <= K && A[i+1] - B[i] <= K){
check[i+1] += 1;
}
if(A[i] - B[i+1] <= K && B[i+1] - A[i] <= K){
check[i+1] += 2;
}else if(B[i] - B[i+1] <= K && B[i+1] - B[i] <= K){
check[i+1] += 2;
}
}
}
if(ans){
cout << "Yes" << endl;
}else{
cout << "No" << endl;
}
return 0;
}