Official

B - 11/11 Editorial by MMNMM


この問題は、次の \(2\) つの方針で解くことができます。

  1. \(1\) 年に存在する日付すべてについて、ゾロ目になっているかチェックする
  2. ゾロ目の日付としてありえるものすべてについて、存在する日付かチェックする

それぞれの方針について解説します。

1. それぞれの日付がゾロ目かチェックする

AtCoder 国の \(1\) 年には \(1\) 月 \(1\) 日から \(N\) 月 \(D _ N\) 日までの \(\displaystyle\sum _ {i=1} ^ ND _ i=D _ 1+D _ 2+\cdots+D _ N\) 日の日付があります。

この日付のすべてについて、ゾロ目になっているか判定して、ゾロ目になる日付がいくつあるか計算することでこの問題を解くことができます。

日付がゾロ目になっているかは、例えば月と日の値を文字列に変換して連結し、\(1\) 種類の文字だけからなるか判定することで判定できます。

実装例は以下のようになります。

N = int(input())
D = [*map(int, input().split())]

ans = 0
for i, d in enumerate(D):
    month_str = str(i + 1)
    for x in range(d):
        day_str = str(x + 1)
        if len(set(month_str + day_str)) == 1:
            ans += 1
            
print(ans)
#include <iostream>
#include <vector>
#include <set>

using namespace std;

int main() {
    int N;
    cin >> N;
    vector<int> D(N);
    for (auto &&d : D)
        cin >> d;

    int ans = 0;
    for (int m = 1; m <= N; ++m) {
        string month = to_string(m);
        for (int d = 1; d <= D[m - 1]; ++d) {
            string date = month + to_string(d);
            if (size(set<char>(date.begin(), date.end())) == 1)
                ++ans;
        }
    }
    cout << ans << endl;

    return 0;
}

2. ゾロ目の日付が存在するかチェックする

この問題の制約のもとで、ゾロ目の日付としてありえるものは \(1\) 月 \(1\) 日、\(1\) 月 \(11\) 日、\(2\) 月 \(2\) 日、\(2\) 月 \(22\) 日、⋯、\(88\) 月 \(8\) 日、\(88\) 月 \(88\) 日、\(99\) 月 \(9\) 日、\(99\) 月 \(99\) 日の \(36\) 通りです。

それぞれの日付が AtCoder 国の暦の中に存在するか判定することでこの問題を解くことができます。

\(i\) 月 \(j\) 日が暦の中に存在しているかは、\(i\) 月が存在し、\(i\) 月が \(j\) 日まであるか判定すればよいです。 存在しない月は \(0\) 日だけあることにしてもよいです。

実装例は以下のようになります。

N = int(input())
D = [*map(int, input().split())]

ans = 0
for i in range(1, 10):
    # i 月 i 日
    if i <= N and i <= D[i - 1]:
        ans += 1
    # i 月 11i 日
    if i <= N and 11 * i <= D[i - 1]:
        ans += 1
    # 11i 月 i 日
    if 11 * i <= N and i <= D[11 * i - 1]:
        ans += 1
    # 11i 月 11i 日
    if 11 * i <= N and 11 * i <= D[11 * i - 1]:
        ans += 1
            
print(ans)
#include <iostream>
#include <vector>
#include <utility>

using namespace std;

int main() {
    int N;
    cin >> N;
    vector<int> D(N);
    for(auto&& d : D)cin >> d;

    vector<pair<int, int>> zorome; // ありえるゾロ目の日付
    for(int i = 1; i <= 9; ++i){
        zorome.emplace_back(i, i);
        zorome.emplace_back(i, i * 11);
        zorome.emplace_back(i * 11, i);
        zorome.emplace_back(i * 11, i * 11);
    }

    int ans{};
    for(const auto& [month, day] : zorome)
        if(month <= N && day <= D[month - 1])
            ++ans;

    cout << ans << endl;
    
    return 0;
}

posted:
last update: