Yukicoder087 Advent Calendar Problem

問題概要

$2015$年-$N$年の間($2015$や$N$も含む)で
yukicoder no.1の出題日(記事中に記載有り)が2014年と同じ曜日になる回数を求めてください。

カレンダーは現実世界と同じものを用いる。

うるう年は通常の判定方法を用いる。
・4で割れる年はうるう年である。
・ただし、100で割れるときは、うるう年ではない。
・ただし、400で割れるときは、うるう年である。
西暦N年の時点でもグレゴリオ暦を用いるとする。

$N\leqq10^{10}$

yukicoder087

解法

target day: 2014年7月23日(水)
なんでFOR(i,2015,2015+(N-2014)%400)はOKで
FOR(i,2014 + t*400 + 1, N)はだめなんや? -> mod400の値がずれるため

計算量:$O(1)$

ソース

    #include <bits/stdc++.h>
    using namespace std;
    
    using LL = long long;
    #define FOR(i, s, e) for (LL(i) = (s); (i) < (e); (i)++)
    
    int main() {
        cin.tie(0);
        ios_base::sync_with_stdio(false);
        //400年分単位で計算し、のこりはシュミレーション
    
        LL N; cin >> N;
    
        LL t = (N - 2014) / 400;
        LL ans = 0;
        {// block
            LL K = 0; LL sum = 0;
            FOR(i, 2015, 2015 + 400) {
                if (i % 400 == 0)sum += 2;
                else if (i % 100 == 0)sum += 1;
                else if (i % 4 == 0)sum += 2;
                else sum += 1;
                if (sum % 7 == 0)K++;
            }
            ans += t * K;
        }
        LL s = 2014 + t * 400;
    
        {// sumilation
            LL K = 0; LL sum = 0;
            FOR(i, 2015, 2015 + (N - 2014) % 400) {
                if (i % 400 == 0)sum += 2;
                else if (i % 100 == 0)sum += 1;
                else if (i % 4 == 0)sum += 2;
                else sum += 1;
                if (sum % 7 == 0)K++;
            }
            ans += K;
        }
        cout << ans << endl;
    
        return 0;
    }
Share Comments
̃Gg[͂ĂȃubN}[Nɒlj
comments powered by Disqus