結果
問題 | No.294 SuperFizzBuzz |
ユーザー | codershifth |
提出日時 | 2016-05-08 13:30:12 |
言語 | C++11 (gcc 11.4.0) |
結果 |
AC
|
実行時間 | 213 ms / 5,000 ms |
コード長 | 3,121 bytes |
コンパイル時間 | 1,737 ms |
コンパイル使用メモリ | 169,320 KB |
実行使用メモリ | 5,248 KB |
最終ジャッジ日時 | 2024-10-05 10:41:04 |
合計ジャッジ時間 | 3,672 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,248 KB |
testcase_02 | AC | 211 ms
5,248 KB |
testcase_03 | AC | 1 ms
5,248 KB |
testcase_04 | AC | 2 ms
5,248 KB |
testcase_05 | AC | 2 ms
5,248 KB |
testcase_06 | AC | 1 ms
5,248 KB |
testcase_07 | AC | 2 ms
5,248 KB |
testcase_08 | AC | 14 ms
5,248 KB |
testcase_09 | AC | 105 ms
5,248 KB |
testcase_10 | AC | 208 ms
5,248 KB |
testcase_11 | AC | 209 ms
5,248 KB |
testcase_12 | AC | 213 ms
5,248 KB |
testcase_13 | AC | 211 ms
5,248 KB |
testcase_14 | AC | 210 ms
5,248 KB |
ソースコード
#include <bits/stdc++.h> typedef long long ll; typedef unsigned long long ull; #define FOR(i,a,b) for(int (i)=(a);i<(b);i++) #define REP(i,n) FOR(i,0,n) #define RANGE(vec) (vec).begin(),(vec).end() using namespace std; class nComb { std::vector<std::vector<long long>> impl_; public: // O(maxN^2) nComb(int maxN, int Mod=1) { impl_.resize(maxN+1, std::vector<long long>(maxN+1, 0)); for (int n = 0; n < maxN; ++n) { impl_[n][0] = 1; for (int r = 0; r <= n; ++r) { impl_[n+1][r+1] = (impl_[n][r+1]+impl_[n][r]); if (Mod > 1) impl_[n+1][r+1] %= Mod; } } } long long operator()(int n, int r) { return impl_[n][r]; } }; class SuperFizzBuzz { public: void solve(void) { int N; cin>>N; // // 整数 n が 3 で割り切れるための必要十分条件は // 各桁の和が 3 で割り切れること // 整数 n が 5 で割り切れるための必要十分条件は // 末尾桁の数字が 5 で割り切れること // // よって n 桁の SuperFizzBuzz の数は // // 5 が 3 の倍数個出現するので(そうしないと各桁の和が 3 の倍数にならない) // // n-1 // Σn-1Ci 個となる // i=0,(i+1)%3==0 // // サンプルより n の上限は 25 だとわかっている // nComb nCr(30); // 目的の N 番目の SuperFizzBuzz が何桁か求める function<int(int)> calc=[&](int n)->int { int k = 0; REP(i,n) { if ((i+1)%3==0) k += nCr(n-1,i); } return k; }; int n = 0; int prev = 0; int total = 0; for (n = 0; n <= 25; ++n) { prev = total; total += calc(n); if (total >= N) break; } // 全探索 n<=25 より高々 2^25 int m = 0; string ans = ""; N -= prev; // n がきまると二値で表現できる // 0 が 3 // 1 が 5 に対応 // 00000...01 (n桁) = 333...35 から始める for (int bit = 1; bit < (1<<(n+1)); ++bit) { if (!(bit & 0x1)) continue; if (__builtin_popcount(bit) %3 != 0 ) continue; ++m; if (m == N) { REP(i,n) { if (bit&(1<<i)) ans += "5"; else ans += "3"; } reverse(RANGE(ans)); cout<<ans<<endl; } } return; } }; #if 1 int main(int argc, char *argv[]) { ios::sync_with_stdio(false); auto obj = new SuperFizzBuzz(); obj->solve(); delete obj; return 0; } #endif