公式

B - Subsegment Reverse 解説 by physics0523


初心者の方へ

方針1. 実際に数列を作って反転する

例えば、実際に数列 \(A=(1,2,\dots,N)\) を配列で作った後に \(L\) 項目から \(R\) 項目までを逆順に並べて出力することでこの問題に正解できます。
配列の連続した部分列の反転にはいくつかの方法があります。

  • 最初 \(l=L,r=R\) として、 \(l<r\) である限り以下を繰り返す。
    • \(l\) 項目と \(r\) 項目を入れ替えた後、 \(l\)\(1\) 加算、 \(r\) から \(1\) 減算する。
  • 標準ライブラリの機能を利用する。

配列の使い方によっては初項が \(0\) 番になることに注意してください。

実装例1 (C++):

#include<bits/stdc++.h>

using namespace std;

int main(){
  int N,L,R;
  cin >> N >> L >> R;
  vector<int> A(N+5);
  for(int i=1;i<=N;i++){
    A[i]=i;
  }
  while(L<R){
    swap(A[L],A[R]);
    L++; R--;
  }
  for(int i=1;i<=N;i++){
    if(i!=1){cout << " ";}
    cout << A[i];
  }cout << "\n";
  return 0;
}

実装例2 (C++):

#include<bits/stdc++.h>

using namespace std;

int main(){
  int N,L,R;
  cin >> N >> L >> R;
  vector<int> A(N+5);
  for(int i=1;i<=N;i++){
    A[i]=i;
  }
  reverse(A.begin()+L,A.begin()+R+1);
  for(int i=1;i<=N;i++){
    if(i!=1){cout << " ";}
    cout << A[i];
  }cout << "\n";
  return 0;
}

方針2. 数列を直接構築する

答えの数列は以下の構造になります。

  • 最初に \(1,2,\dots,L-1\) をこの順に並べる。
  • 次に \(R,R-1,\dots,L\) をこの順に並べる。
  • 最後に \(R+1,R+2,\dots,N\) をこの順に並べる。

これを for ループなどを用いて直接構築すればよいです。

実装例(C++):

#include<bits/stdc++.h>

using namespace std;

int main(){
  int N,L,R;
  cin >> N >> L >> R;
  vector<int> res;

  for(int i=1;i<=L-1;i++){res.push_back(i);}
  for(int i=R;i>=L;i--){res.push_back(i);}
  for(int i=R+1;i<=N;i++){res.push_back(i);}

  for(int i=0;i<N;i++){
    if(i){cout << " ";}
    cout << res[i];
  }cout << "\n";
  return 0;
}

投稿日時:
最終更新: