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";
}   

投稿日時:
最終更新: