AtCoder が提供しているABC(AtCoder Beginner Contest)277 のB問題をC++とPythonで解いてみました。ABC277は、2022年11月12日21:00に実施されました。
AtCoder の紹介はこちらに、プログラミングの方針はこちらに記事があります。
B問題 Playing Cards Validation(Difficulty : 60)
問題はリンク先をご覧ください。
ABC277 B問題 Playing Cards Validation
トランプのカードを表す一組の文字列が正しいか判断する問題です。AtCoder Problems による Difficulty は、60 でした。
解答案
問題を解く方針を書きだします。
- N 個の文字列を読み込む。
- 以下の条件を確認する。
- 1文字目が H、D、C、S のどれかである。
- 2文字目が A、2、3、…、9、T、J、Q、K のどれかである。
- 文字列がすべて異なる
- 確認結果に従い、”Yes” か ”No” を出力する。
C++ プログラム例(ABC277B)
最初の版では、候補の文字を char 配列 mark 、number として用意しました。候補の文字のどれかに一致しているかを判断しています。文字列がすべて異なっているかは、set コンテナ u に登録して、u に登録された個数が N に等しいか調べています。
また、条件を満たさないことが判明した時点で、”No” を出力して、プログラムを終了しています。
#include <bits/stdc++.h>
using namespace std;
int main()
{
char mark[] = {'H', 'D', 'C', 'S'};
char number[] = {'A', '2', '3', '4', '5', '6', '7'
, '8', '9', 'T', 'J', 'Q', 'K'};
int n;
cin >> n;
vector<string> s(n);
set<string> u;
for (int i = 0; i < n; ++i) {
cin >> s[i];
u.insert(s[i]);
}
for (int i = 0; i < n; ++i) {
bool b = false;
for (int j = 0; j < 4; ++j) {
if (s[i][0] == mark[j]) {
b = true;
}
}
if (!b) {
cout << "No" << endl;
return 0;
}
b = false;
for (int j = 0; j < 13; ++j) {
if (s[i][1] == number[j]) {
b = true;
}
}
if (!b) {
cout << "No" << endl;
return 0;
}
}
if (u.size() != n) {
cout << "No" << endl;
return 0;
}
cout << "Yes" << endl;
return 0;
}
最初の版から以下2点を改良します。
- char 配列ではなく、文字列を用意して count 関数で判断する。
- 複数の return で制御を抜けていて、プログラミング作法上、好ましくない。bool 変数 result に判定結果を保持して、最後に出力する。
この改良2点に対応したプログラムが以下です。最初の版より読みやすくなっています。
#include <bits/stdc++.h>
using namespace std;
int main()
{
string mark = "HDCS";
string number = "A23456789TJQK";
int n;
cin >> n;
vector<string> s(n);
set<string> u;
for (int i = 0; i < n; ++i) {
cin >> s[i];
u.insert(s[i]);
}
bool result = true;
for (int i = 0; i < n; ++i) {
if (count(mark.begin(), mark.end(), s[i][0]) == 0) {
result = false;
}
if (count(number.begin(), number.end(), s[i][1]) == 0) {
result = false;
}
}
if (u.size() != n) {
result = false;
}
if (result) {
cout << "Yes" << endl;
} else {
cout << "No" << endl;
}
return 0;
}
どちらも AC(Accepted=正しいプログラム)と判定されました。
Python プログラム例(ABC277B)
Python 版は、C++ 後者の版をベースにしました。文字列の重複は set を使って確認しました。
"""AtCoder Beginner Contest 277 B"""
n = int(input())
s = [input() for i in range(n)]
mark = "HDCS"
number = "A23456789TJQK"
u = set()
for i in range(n):
u.add(s[i])
result = True
for i in range(n):
if mark.count(s[i][0]) == 0:
result = False
if number.count(s[i][1]) == 0:
result = False
if len(u) != n:
result = False
print("Yes" if result else "No")
こちらも「AC」と判定されました。
最後に
この問題は、条件を漏れなくプログラムできるかが問われています。問題文には、3つの条件が明記されていました。文字列と、重複がないコンテナの操作によって、条件を判断することができました。
引き続き ABC の問題を紹介していきます。