AtCoder が提供しているABC(AtCoder Beginner Contest)286 のA問題をC++とPythonで解いてみました。ABC286は、2023年1月21日21:00に実施されました。
AtCoder の紹介はこちらに、プログラミングの方針はこちらに記事があります。
A問題 Range Swap(Difficulty : 30)
問題はリンク先をご覧ください。
与えられた数列の一部を入れ替える問題です。AtCoder Problems による Difficulty は 30 でした。
解答案
問題を解く方針を書きだします。
- N、P、Q、R、S を読み込む。
- 数列 Ai を読み込む。
- 数列 Ai の一部を入れ替えて、Bi を生成する。
- 数列 Bi を出力する。
C++ プログラム例(ABC286A)
このような問題を解く場合、問題に合わせて数列の添え字を1からカウントするか、言語が用意する配列に合わせて0からカウントするか、プログラムの細部が分かれます。
この問題は、添え字を扱うため、問題に合わせて数列を1からカウントします。このとき、配列 A と B の個数を N + 1 個用意する必要があります。また、A[0]、B[0] は確保されていますが使いません。メリットとして、プログラムは分かりやすくなります。
問題の題意に従い、配列 A の先頭から配列 B を定めていきます。その後で配列 B を出力します。以下が C++ プログラムです。A問題としては、やや長くなっています。
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n, p, q, r, s;
cin >> n >> p >> q >> r >> s;
vector<int> a(n + 1);
for (int i = 1; i <= n; ++i) {
cin >> a[i];
}
vector<int> b(n + 1);
for (int i = 1; i < p; ++i) {
b[i] = a[i];
}
for (int i = p; i <= q; ++i) {
b[i] = a[r + i - p];
}
for (int i = q + 1; i < r ; ++i) {
b[i] = a[i];
}
for (int i = r; i <= s; ++i) {
b[i] = a[p + i - r];
}
for (int i = s + 1; i <= n; ++i) {
b[i] = a[i];
}
for (int i = 1; i <= n; ++i) {
cout << b[i] << " \n"[i == n];
}
return 0;
}
AC(Accepted=正しいプログラム)と判定されました。
Python プログラム例(ABC286A)
Python 版も C++ 版と同じく、リストの添え字を1からカウントします。このため、数列を読み込んだ後、A[0] を挿入しています(4行目)。リスト A からリスト B をスライス表記を使って生成しています。
"""AtCoder Beginner Contest 286 A"""
n, p, q, r, s = map(int, input().split())
a = list(map(int, input().split()))
a.insert(0, 0)
b = [0] * (n + 1)
b[1:p] = a[1:p]
b[p:q + 1] = a[r:s + 1]
b[q + 1:r] = a[q + 1:r]
b[r:s + 1] = a[p:q + 1]
b[s + 1:n + 1] = a[s + 1:n + 1]
print(*(b[1:]))
上記のプロラムは、Python らしくないかもしれません。リスト A をスライス表記と多重代入を使って書き換えます(6行目)。こちらのプログラムの方が、すっきりと書けています。
"""AtCoder Beginner Contest 286 A"""
n, p, q, r, s = map(int, input().split())
a = list(map(int, input().split()))
a.insert(0, 0)
a[p:q + 1], a[r:s + 1] = a[r:s + 1], a[p:q + 1]
print(*(a[1:]))
どちらも「AC」と判定されました。
最後に
A問題としては、多少難しかったかもしれません。プログラムに慣れていない場合、添え字を問題に合わせるか、言語に合わせるかは、決めた方が良いかもしれません。
引き続き ABC の問題を紹介していきます。