AtCoder が提供しているABC(AtCoder Beginner Contest)281 のB問題をC++とPythonで解いてみました。ABC281は、2022年12月10日21:00に実施されました。
AtCoder の紹介はこちらに、プログラミングの方針はこちらに記事があります。
B問題 Sandwich Number(Difficulty : 66)
問題はリンク先をご覧ください。
文字列が条件を満たしているか確認する問題です。AtCoder Problems による Difficulty は、66 でした。
解答案
問題を解く方針を書きだします。
- 文字列S を読み込む。
- S の先頭から、条件を確認していく。
- S[0]は、英字大文字
- S[1]は、1以上の数字
- S[2]からS[6]は、数字
- S[7]は、英字大文字
- 条件を満たしていれば、”Yes” を、満たしていなければ、”No” を出力します。
C++ プログラム例(ABC281B)
一般的な英字大文字や数字は、文字コード上で連続に並んでいます。その性質を使って、条件を満たしているか確認します。
なお、配列の領域外アクセスを避けるために、文字列の長さが8でなければ、”No” を出力して、プログラムを終了しています。
#include <bits/stdc++.h>
using namespace std;
int main()
{
string s;
cin >> s;
bool result = true;
if(s.length() != 8) {
cout << "No" << endl;
return 0;
}
if ((s[0] < 'A')||('Z' < s[0])) {
result = false;
}
if ((s[1] < '1')||('9' < s[1])) {
result = false;
}
for (int i = 2; i < 7; ++i) {
if ((s[i] < '0')||('9' < s[i])) {
result = false;
}
}
if ((s[7] < 'A')||('Z' < s[7])) {
result = false;
}
if (result) {
cout << "Yes" << endl;
} else {
cout << "No" << endl;
}
return 0;
}
C 標準ライブラリ isupper と isdigit を使った例も示します。S[1] を先に文字として ‘0’ の場合を確認します。その次に、S[1] から S[6] まで、isdigit で確認するように変更しました。
条件式をすっきり書くことができています。
#include <bits/stdc++.h>
using namespace std;
int main()
{
string s;
cin >> s;
bool result = true;
if(s.length() != 8) {
cout << "No" << endl;
return 0;
}
if (!isupper(s[0])) {
result = false;
}
if ((s[1] == '0')) {
result = false;
}
for (int i = 1; i < 7; ++i) {
if (!isdigit(s[i])) {
result = false;
}
}
if (!isupper(s[7])) {
result = false;
}
if (result) {
cout << "Yes" << endl;
} else {
cout << "No" << endl;
}
return 0;
}
どちらもAC(Accepted=正しいプログラム)と判定されました。
Python プログラム例(ABC281B)
Python も、C 標準ライブラリとほぼ同じ趣旨のメソッドが用意されています。isalpha は、英字か判定するメソッドですが、問題文の制約に「S は英大文字と数字からなる」と明記されているため、問題ありません。
"""AtCoder Beginner Contest 281 B"""
import sys
s = input()
result = True
if len(s) != 8:
print("No")
sys.exit()
if not s[0].isalpha():
result = False
if s[1] == "0":
result = False
for i in range(1, len(s) - 1):
if not s[i].isdecimal():
result = False
if not s[7].isalpha():
result = False
print("Yes" if result else "No")
こちらも「AC」と判定されました。
最後に
この問題は、それほど難しくはないように見えます。ただし、以下のような考慮が抜ける場合もあり得ます。
- 先頭からの8文字だけ確認していて、9文字以上の文字列に対して “Yes” と判定する。
- 数字が6桁の数ではない場合(012345 など)も、”Yes” と判定する。
問題文を速く正確に理解して、このようなミスは避けたいです。
引き続き ABC の問題を紹介していきます。