AtCoder

ABC281 B問題(Sandwich Number)を解く

AtCoder_ABC281_B

AtCoder が提供しているABC(AtCoder Beginner Contest)281 のB問題をC++とPythonで解いてみました。ABC281は、2022年12月10日21:00に実施されました。

AtCoder の紹介はこちらに、プログラミングの方針はこちらに記事があります。

B問題 Sandwich Number(Difficulty : 66)

問題はリンク先をご覧ください。

ABC281 B問題 Sandwich Number

文字列が条件を満たしているか確認する問題です。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 の問題を紹介していきます。

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA