けんちょんの競プロ精進記録

競プロの精進記録や小ネタを書いていきます

AtCoder ABC 286 A - Range Swap (7Q, 灰色, 100 点)

意外と実装に手こずった人も多いかもしれない。上手に for 文で実装できる操作に言い換えていこう!

問題概要

長さ  N の数列  A_{1}, A_{2}, \dots, A_{N} が与えられる。

今、 1 \le P \le Q \lt R \le S \le N かつ  Q - P = S - R をみたす 4 つの整数  P, Q, R, S が与えられる。

数列  A P 番目から  Q 番目の項までと、 R 番目から  S 番目の項とを入れ替えた数列を求めよ。

考えたこと

操作の内容が複雑なので「このようなことを実現できる関数はないだろうか......」などと考えると詰まってしまう。ここでは、次のように考えよう。次のことを順次行っていけばよいのだ。


  • 数列の  P 番目と  R 番目を swap する
  • 数列の  P + 1 番目と  R + 1 番目を swap する
  • 数列の  P + 2 番目と  R + 2 番目を swap する
  • ...
  • 数列の  Q 番目と  S 番目を swap する

つまり、 i = 0, 1, \dots, Q - P に対して、数列の  P + i 番目と  R + i 番目を swap していけばよい。

コード

#include <bits/stdc++.h>
using namespace std;

int main() {
    int N, P, Q, R, S;
    cin >> N >> P >> Q >> R >> S;
    --P, --Q, --R, --S;  // 0 始まりにする

    vector<int> A(N);
    for (int i = 0; i < N; i++) cin >> A[i];

    for (int i = 0; i <= Q - P; i++) {
        swap(A[P + i], A[R + i]);
    }

    for (int i = 0; i < N; i++) cout << A[i] << " ";
    cout << endl;
}