Official
B - Blank Bingo Editorial
by
B - Blank Bingo Editorial
by
KumaTachiRen
Editorial for printing
マス目において一列に並んだ \(5\) マスの集合としてあり得るものすべてについて「その \(5\) マスのうち印が書き込まれていないマスの数(\(S\) の対応する文字が . であるマスの数)」の最小値が答えになります。
縦方向の \(5\) 列、横方向の \(5\) 列をまとめて処理すると実装量が削減できます。
実装例 (C++)
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<string> S(5);
for (auto& s : S) cin >> s;
int ans = 5;
// 横
for (int k = 0; k < 5; k++) {
int count = 0;
for (int i = 0; i < 5; i++)
if (S[k][i] == '.') count++;
ans = min(ans, count);
}
// 縦
for (int k = 0; k < 5; k++) {
int count = 0;
for (int i = 0; i < 5; i++)
if (S[i][k] == '.') count++;
ans = min(ans, count);
}
// 斜め
{
int count = 0;
for (int i = 0; i < 5; i++)
if (S[i][i] == '.') count++;
ans = min(ans, count);
}
{
int count = 0;
for (int i = 0; i < 5; i++)
if (S[i][4 - i] == '.') count++;
ans = min(ans, count);
}
cout << ans << "\n";
}
さらに「指定したマスから指定した方向に連続する \(5\) マス」について計算するようにすると、縦・横・斜めを一括で扱うことができます。この方針の場合、関数やラムダ式を利用すると簡潔に書けます。
実装例 (C++)
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<string> S(5);
for (auto& s : S) cin >> s;
int ans = 5;
auto check = [&](int x0, int y0, int dx, int dy) {
int count = 0;
for (int i = 0; i < 5; i++)
if (S[x0 + dx * i][y0 + dy * i] == '.') count++;
ans = min(ans, count);
};
for (int k = 0; k < 5; k++) check(k, 0, 0, 1);
for (int k = 0; k < 5; k++) check(0, k, 1, 0);
check(0, 0, 1, 1);
check(0, 4, 1, -1);
cout << ans << "\n";
}
また Python では \(S_1,\dots,S_5\) を一つの文字列に結合し、スライスと .count() を利用することでも実装できます。
実装例 (Python)
S = [input() for _ in range(5)]
SS = "".join(S)
ans = 5
for k in range(5):
ans = min(ans, S[k].count("."))
for k in range(5):
ans = min(ans, SS[k::5].count("."))
ans = min(ans, SS[0::6].count("."))
ans = min(ans, SS[4:-1:4].count("."))
print(ans)
posted:
last update:
