AtCoder

ABC328 B問題(11/11)を解く

AtCoder_ABC328_B

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

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

B問題 11/11(Difficulty : 86)

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

ABC328 B問題 11/11

11月11日のようにゾロ目になっている日数を求めます。AtCoder Problems による Difficulty は 86 でした。

解答案

以下の2つの方針でゾロ目の日数を求めます。

  • 日付がゾロ目になるのは、各月多くとも2日となります。その2日が条件を満たすか調べます。
  • 月と日について、文字列に変換して文字種がひとつか全探索して調べます。

C++ プログラム例(ABC328B)

制約から $1 \leqq N \leqq 100$、$1 \leqq D_i \leqq 100$ となります。月または日が100になる場合、ゾロ目になりません。このため、各月のゾロ目になる日付は1桁の場合と2桁の場合で、たかだか2日しかありません。

以下の手順でソロ目となる日付の日数を求めます。

  • 月が2桁の場合、その月自体がゾロ目になっていないと日付はゾロ目になりません(18行目)。それぞれの月に対して、以下を調べます。
    • 日が1桁の場合、月が持つ数字と一致している日が $D_i$ 以下か調べます(22行目)。
    • 日が2桁の場合も、同じように $D_i$ 以下か調べます(24行目)。

以下が、C++プログラムとなります。

#include <bits/stdc++.h>
using namespace std;

int main()
{
	int n;
	cin >> n;
	vector<int> d(n + 1);
	for (int i = 1; i <= n; ++i) {
		cin >> d[i];
	}

	int result = 0;
	for (int i = 1; i <= n; ++i) {
		if (i == 100) {
			continue;
		}
		if ((i >= 10)&&(i / 10 != i % 10)) {
			continue;
		}
		int day = i % 10;
		if (day <= d[i]) {
			++result;
			if (day * 10 + i % 10 <= d[i]) {
				++result;
			}
		}
	}

	cout << result << endl;

	return 0;
}

文字列で判定するプログラムも紹介します。この場合、日付に使われている文字列の文字種が1種類か調べます。文字種は set コンテナを使いました(17、18行目)。月と日について全探索します。

前者と比較して、すっきりとプログラムが書けています。以下となります。

#include <bits/stdc++.h>
using namespace std;

int main()
{
	int n;
	cin >> n;
	vector<int> d(n + 1);
	for (int i = 1; i <= n; ++i) {
		cin >> d[i];
	}

	int result = 0;
	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j <= d[i]; ++j) {
			string date = to_string(i) + to_string(j);
			set<char> s(date.begin(), date.end());
			if (s.size() == 1) {
				++result;
			}
		}
	}

	cout << result << endl;

	return 0;
}

どちらも AC(Accepted=正しいプログラム)と判定されました。

Python プログラム例(ABC328B)

Python 版も基本的な考え方は同じです。C++の最初のプログラムは以下となります。

"""AtCoder Beginner Contest 328 B"""
n = int(input())
d = list(map(int, input().split()))
d.insert(0, 0)

result = 0
for i in range(1, n + 1):
    if i == 100:
        continue
    if i >= 10 and i // 10 != i % 10:
        continue
    day = i % 10
    if day <= d[i]:
        result += 1
        if day * 10 + i % 10 <= d[i]:
            result += 1

print(result)

文字に変換して解くプログラムも紹介します。

"""AtCoder Beginner Contest 328 B"""
n = int(input())
d = list(map(int, input().split()))
d.insert(0, 0)

result = 0
for i in range(1, n + 1):
    for j in range(1, d[i] + 1):
        date = str(i) + str(j)
        s = set(date)
        if len(s) == 1:
            result += 1

print(result)

こちらも「AC」と判定されました。

最後に

コンテストでは、前者のプログラムを提出しました。公式解説を読み、文字列で解く方が簡単なプログラムになることが分かり、文字列として解くプログラムも紹介しました。

整数の問題を文字列として解く類題として、ABC304B問題解説記事)があります。

引き続き ABC の問題を紹介していきます。

COMMENT

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

CAPTCHA