D - RLE Moving 解説
by
karinohito
公式解説の後半部分の方法により, \(M=L=1\) の問題が解ければ良いです。
\(S_1'=T_1'\) の時
\((R_t,C_t)=(R_a,C_a)\) ならば答えは \(A_1(=B_1)\) であり, そうでなければ答えは \(0\) です.
\(S_1'\neq T_1'\) の時
二人の座標のマンハッタン距離 \(|R_t-R_a|+|C_t-C_a|\) を \(d\) とすると, 二人が出会うならばそれは丁度 \(d/2\) 回の移動の後です. よって,
- \(d\) が偶数.
- \(0<d/2\le A_1(=B_1).\)
- 二人の \(d/2\) 回の移動後の座標が等しい.
の \(3\) 条件が全て満たされるならば答えは \(1\) でそうでない時答えは \(0\) です.
#include<bits/stdc++.h>
using namespace std;
using ll =long long;
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
ll C_t,R_t,C_a,R_a,N,M,L;
cin>>R_t>>C_t>>R_a>>C_a>>N>>M>>L;
deque<array<ll,3>> S,T;
/// 文字を方向に変換しつつ入力を受け取る---ここから---
for(int i=0;i<M;i++){
char s;
ll a;
cin>>s>>a;
if(s=='U')S.push_back({a,-1,0});
else if(s=='D')S.push_back({a,1,0});
else if(s=='R')S.push_back({a,0,1});
else S.push_back({a,0,-1});
}
for(int i=0;i<L;i++){
char s;
ll a;
cin>>s>>a;
if(s=='U')T.push_back({a,-1,0});
else if(s=='D')T.push_back({a,1,0});
else if(s=='R')T.push_back({a,0,1});
else T.push_back({a,0,-1});
}
/// 文字を方向に変換しつつ入力を受け取る---ここまで---
ll an=0;
while(S.size()>0){
/// 同じ方向に移動する部分を抜き出す--ここから--
auto [a,dR_t,dC_t]=S.front();
auto [b,dR_a,dC_a]=T.front();
S.pop_front();
T.pop_front();
if(a<b){
T.push_front({b-a,dR_a,dC_a});
b=a;
}
if(a>b){
S.push_front({a-b,dR_t,dC_t});
a=b;
}
/// 同じ方向に移動する部分を抜き出す--ここまで--
//移動方向が同じケース
if(dR_t==dR_a&&dC_t==dC_a){
if(R_t==R_a&&C_t==C_a){
an+=a;
}
}
else{
ll d=abs(R_t-R_a)+abs(C_t-C_a);//マンハッタン距離
if(
d%2==0&&
0<d&&d/2<=a&&
R_t+dR_t*(d/2)==R_a+dR_a*(d/2)&&C_t+dC_t*(d/2)==C_a+dC_a*(d/2) //d/2回移動後の座標一致
)an++;
}
// 動いた先を求める.
R_t+=dR_t*a;
C_t+=dC_t*a;
R_a+=dR_a*a;
C_a+=dC_a*a;
}
cout<<an<<"\n";
}
投稿日時:
最終更新: