AtCoder が提供しているABC(AtCoder Beginner Contest)385 B問題をC++とPythonで解いてみました。ABC385は、2024年12月21日21:00に実施されました。
AtCoder の紹介はこちらに、プログラミングの方針はこちらに記事があります。
B問題 Santa Claus 1(Difficulty : 77)
問題の詳細は、リンク先をご覧ください。
指示されたようにグリッドを移動します。AtCoder Problems による Difficulty は 77 でした。
解答案
C++ プログラム例(ABC385B)
指定された方向のグリッドを調べて、通行不能でなければ移動します。移動先が家であれば、変数 result
の値を増やして、家を訪問済みとします(文字を ‘.’ に置き換えます)。
以下の制約でプログラムが楽になりました。
- 最外周がすべて通行不能(’#’)となっているため、通行可能かどうかの確認だけで、グリッドの範囲内かどうかを調べる必要がありません(19行目など)。
- サンタクロースの初期位置には家がありません。もしこの制約がなければ、18行目の
for
文の前で処理する必要がありました。
以下が、C++プログラムです。
#include <bits/stdc++.h>
using namespace std;
int main()
{
int h, w, x, y;
cin >> h >> w >> x >> y;
--x;
--y;
vector<string> s(h);
for (int i = 0; i < h; ++i) {
cin >> s[i];
}
string t;
cin >> t;
int result = 0;
for (int i = 0; i < (int)t.length(); ++i) {
if ((t[i] == 'U') && (s[x - 1][y] != '#')) {
--x;
} else if ((t[i] == 'D') && (s[x + 1][y] != '#')) {
++x;
} else if ((t[i] == 'L') && (s[x][y - 1] != '#')) {
--y;
} else if ((t[i] == 'R') && (s[x][y + 1] != '#')) {
++y;
}
if (s[x][y] == '@') {
s[x][y] = '.';
++result;
}
}
cout << x + 1 << " " << y + 1 << " " << result << endl;
return 0;
}
AC(Accepted=正しいプログラム)と判定されました。
Python プログラム例(ABC385B)
基本的な考え方は同じです。Python の文字列は書き換えができないため、リストとして処理します(5ー7行目)。以下がプログラムです。
"""AtCoder Beginner Contest 385 B"""
h, w, x, y = map(int, input().split())
x -= 1
y -= 1
s = [['.' for _ in range(w)] for _ in range(h)]
for i in range(h):
s[i] = list(input())
t = input()
result = 0
for i in range(len(t)):
if t[i] == 'U' and s[x - 1][y] != '#':
x -= 1
elif t[i] == 'D' and s[x + 1][y] != '#':
x += 1
elif t[i] == 'L' and s[x][y - 1] != '#':
y -= 1
elif t[i] == 'R' and s[x][y + 1] != '#':
y += 1
if s[x][y] == '@':
s[x][y] = '.'
result += 1
print(x + 1, y + 1, result)
こちらも「AC」と判定されました。
最後に
この問題は、制約に配慮されていて実装が簡単になりました。
引き続き ABC の問題を紹介していきます。