D - Gathering Children

・問題URL

https://atcoder.jp/contests/abc136/tasks/abc136_d

・発想

・10¹⁰⁰回シミュレーションするのは無理。
・出力例を見ると、00120003400みたいに0の塊と1以上の塊がある。そうか、RLで挟まれるとそこを右往左往するだけか。しかも端っこは抜け出せないようになってるから絶対RRR・・・RRLL・・・LLLが何回か続く形の入力。
・RLの変わり目に人があつまって(10¹⁰⁰がバカでかいので絶対全員変わり目に行き着く)、その人数はRRR・・・RRLL・・・LLLのなかでなんか偶奇とか調べればよさそう()。

・解法

実装途中でこんがらがったので、もうSの部分列RRR・・・RRLL・・・LLLだけの答えを出力するだけの関数を作った。これを何回か呼び出す。偶奇の場合分けは紙に書いたら整理できた。下のコードでは、入力したSの最後にRを付けて文字列を切断する工夫をした。

・コード

void howmany(string T){
 
 int N=T.size();
 int a=0;
 
 rep(i,N){
   if(T[i]=='R')a++;
 }
 if(a%2==1){
   rep(i,a-1)cout<<0<<" ";
   cout<<(N+2-1)/2<<" ";
   cout<<N-(N+2-1)/2<<" ";
   for(int i=a+1;i<N;i++)cout<<0<<" ";
 }
 else {
   rep(i,a-1)cout<<0<<" ";
   cout<<N-(N+2-1)/2<<" ";
   cout<<(N+2-1)/2<<" ";
   for(int i=a+1;i<N;i++)cout<<0<<" ";
 }

}

int main(){
  
 string S;
 cin>>S;
 S+='R';//工夫
 int N=S.size();
 vector<int>ans(N,0);
 bool Q=false;
 vector<string>A;
 string T="";
 
 rep(i,N){
   if(Q&&S[i]=='R'){
     A.push_back(T);
     T="";
     Q=false;
     i--;
   }
   else if(!Q&&S[i]=='R')T+='R';
   else if(S[i]=='L'){
     T+='L';
     Q=true;
   }
 }

 for(auto v:A)howmany(v);
  

}

この記事が気に入ったらサポートをしてみませんか?