Official

B - Playing Cards Validation Editorial by cn449


この問題では、与えられた条件を for 文と if 文を用いて丁寧に処理すればよいですが、何点か実装に関して気を付けるとよいことがあります。

「すべての条件を満たす」の処理に関して

以下のような方針が考えられます(あくまで例であり、他の方針でも正しく動けば問題ないです)。

  • 答えとなる変数を True で初期化して持つ。各条件に対して判定を行い、条件に反するものがあった場合その変数を False へと変更する。
  • 各条件に対して判定を行い、条件に反するものがあった場合Noを出力しプログラムを終了する。最後まで実行された場合、Yesを出力する。

\(2\) つめの条件に関して

素直に判定を行おうとすると

for (int i = 0; i < n; i++) {
	if (s[i][1] == 'A' or s[i][1] == '2' or s[i][1] == '3' or s[i][1] == '4' or s[i][1] == '5' or s[i][1] == '6' or s[i][1] == '7' or s[i][1] == '8' or s[i][1] == '9' or s[i][1] == 'T' or s[i][1] == 'J' or s[i][1] == 'Q' or S[i][1] == 'K') {
		// 処理を行う
	}
}

あるいは

for (int i = 0; i < n; i++) {
	if (s[i][1] != 'A' and s[i][1] != '2' and s[i][1] != '3' and s[i][1] != '4' and s[i][1] != '5' and s[i][1] != '6' and s[i][1] != '7' and s[i][1] != '8' and s[i][1] != '9' and s[i][1] != 'T' and s[i][1] != 'J' and s[i][1] != 'Q' and S[i][1] != 'K') {
		// 処理を行う
	}
}

などのように多くの条件を繋いで並べるという方針が考えられますが、この方針ではタイプ量が多くなりミスが生じやすいため、別の方法により処理することを推奨します。
たとえば、C++ であれば

string s2 = "A23456789TJQK";
for (int i = 0; i < n; i++) {
	if (!count(s2.begin(), s2.end(), s[i][1])) // 処理を行う
}

Python であれば

s2 = "A23456789TJQK"
for i in range(n):
	if !s2.count(s[i][1]):
		# 処理を行う

などの記述が簡潔でしょう(これに関しても当然他の楽な方針も存在します)。もちろんこれは \(1\) つめの条件に対しても使うことができます。

\(3\) つめの条件に関して

もちろん set などを用いることにより高速に判定してもよいですが、制約が小さいため単に \(2\) 重ループを回しても何の問題もないことに注意してください。本問題では実装量はさほど変わりませんが、TL に十分余裕があると考えられる場合は計算量を多少犠牲にして楽な実装をするというのも競技プログラミングの戦略の一種です。また、\(2\) 重ループを回す際には \(i\)\(j\) の対称性より大小関係を決め打っても問題がないです。

実装例(C++)

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

int main() {
	int n;
	cin >> n;
	vector<string> s(n);
	for (int i = 0; i < n; i++) cin >> s[i];
	bool ans = true;
	for (int i = 0; i < n; i++) for (int j = 0; j < i; j++) if (s[i] == s[j]) ans = false;
	string s1 = "HDCS";
	string s2 = "A23456789TJQK";
	for (int i = 0; i < n; i++) {
		if (!count(s1.begin(), s1.end(), s[i][0]) || !count(s2.begin(), s2.end(), s[i][1])) ans = false;
	}
	cout << (ans ? "Yes" : "No") << '\n';
}

実装例(Python)

n = int(input())
s = [input() for _ in range(n)]
s1 = "HDCS"
s2 = "A23456789TJQK"
ans = True
for i in range(n):
	for j in range(i):
		if s[i] == s[j]:
			ans = False
for i in range(n):
	if not s1.count(s[i][0]) or not s2.count(s[i][1]):
		ans = False
print("Yes" if ans else "No")

posted:
last update: