2016-06-26 3 views
2

USACO 1.1 – Friday the Thirteenth問題はさまざまな方法で何度も解決されています。確かにそれは様々なソリューションをStackOverflowの上での質問の一握りを生成した:解決USACO 1.1 - 金曜日13日目date.h

質問です:何だろうのように見えるソリューション私がリンクしたような?

これは他のソリューションよりも大幅に簡単ですか?書きやすい?もっと効率的?

+1

カノニカルが早い段階でこのような疑問を解決するための素晴らしい試み:-) ...(今日の投票では、申し訳ありません) –

答えて

5

問題文は、各月の13日が特定の曜日になる頻度を[1900-01-01, 2300-01-01)の範囲でカウントすることです。

date.hを使用し、これは非常に簡単かつ効率的に達成このようなものです:

#include "date.h" 
#include <iostream> 

int 
main() 
{ 
    using namespace date; 
    unsigned freq[7] = {}; 
    for (auto ym = 1900_y/jan; ym < 2300_y/jan; ym += months{1}) 
     freq[unsigned{weekday{ym/13}}]++; 
    for (unsigned i = 0; i < 7; ++i) 
     std::cout << weekday{i} << " : " << freq[i] << '\n'; 
} 

ymdate::year_monthオブジェクトです。これはtime_pointのように考えることができますが、それはmonthsの非常に粗い精度を持っています。

毎年、毎月の各月をループし、その月の13日の曜日を計算し、weekdayunsignedにキャストするだけです。

高度な構文は非常に単純であり、読みやすいです。

フード下のアルゴリズムはdays_from_civilweekday_from_daysです。これらの低レベル日付アルゴリズムのいずれも反復的ではないので、非常に効率的です。つまり、読みやすい高水準の構文と高性能の両方を実現できます。

この単純なプログラムの出力も非常に読みやすいです:

Sun : 687 
Mon : 685 
Tue : 685 
Wed : 687 
Thu : 684 
Fri : 688 
Sat : 684 

これは、13日の金曜日は少し可能性が高い他の曜日よりも判明しました。

C++では1Z(C++ 17私たちは願っています)、あなたもこれらの結果とconstexpr std::array<unsigned, 7>(いくつかの理由は、コンパイル時に、このような数字を持っていることが重要でなければなりません)を作成することができるようになります。

このアセンブリを生成
#include "date.h" 
#include <array> 
#include <iostream> 

constexpr 
std::array<unsigned, 7> 
compute_freq() noexcept 
{ 
    using namespace date; 
    decltype(compute_freq()) freq = {}; 
    for (auto ym = 1900_y/jan; ym < 2300_y/jan; ym += months{1}) 
     freq[unsigned{weekday{ym/13}}]++; 
    return freq; 
} 

constexpr auto freq = compute_freq(); 

int 
main() 
{ 
    using namespace date::literals; 
    static_assert(freq[unsigned{sun}] == 687); 
    static_assert(freq[unsigned{mon}] == 685); 
    static_assert(freq[unsigned{tue}] == 685); 
    static_assert(freq[unsigned{wed}] == 687); 
    static_assert(freq[unsigned{thu}] == 684); 
    static_assert(freq[unsigned{fri}] == 688); 
    static_assert(freq[unsigned{sat}] == 684); 
} 

_freq: 
    .long 687      ## 0x2af 
    .long 685      ## 0x2ad 
    .long 685      ## 0x2ad 
    .long 687      ## 0x2af 
    .long 684      ## 0x2ac 
    .long 688      ## 0x2b0 
    .long 684      ## 0x2ac 

そして、あなたはちょうどそれよりも効率的取得することはできません。

関連する問題