結果
問題 |
No.3242 Count 8 Included Numbers (Hard)
|
ユーザー |
|
提出日時 | 2025-09-26 12:30:47 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 13 ms / 2,000 ms |
コード長 | 1,502 bytes |
コンパイル時間 | 3,803 ms |
コンパイル使用メモリ | 278,704 KB |
実行使用メモリ | 7,716 KB |
最終ジャッジ日時 | 2025-09-26 12:30:57 |
合計ジャッジ時間 | 6,481 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 5 |
other | AC * 20 |
ソースコード
#include <bits/stdc++.h> using namespace std; using ll = long long; #include <atcoder/modint> using namespace atcoder; using mint = modint998244353; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); string n; if(!(cin >> n)) return 0; // dp_tight: これまで N の接頭辞と等しいまま来ていて、かつ '8' を含まない個数 // dp_loose: 途中で N より小さくなっていて、かつ '8' を含まない個数 mint dp_tight = 1, dp_loose = 0; for(char ch : n) { int c = ch - '0'; mint new_loose = dp_loose * 9; // loose -> 次桁も 0..9(ただし8以外) の9通り // tight から「c より小さい」数字を選ぶと loose になる int cnt_lt = c - (c >= 9 ? 1 : 0); // 0..c-1 のうち '8' を除く個数 new_loose += dp_tight * cnt_lt; // tight を維持できるのは、その桁で c を選べて、かつ c != 8 のとき mint new_tight = dp_tight * (c != 8 ? 1 : 0); dp_tight = new_tight; dp_loose = new_loose; } mint no8 = dp_tight + dp_loose; // 0..N で '8' を含まない個数 // N+1 を 998244353 で計算 mint up = 0; for(char ch : n) up = up * 10 + (ch - '0'); up += 1; // N+1 mint ans = up - no8; // 0..N のうち '8' を含む個数 // 問題は 1..N だが、0 は '8' を含まないのでこのままで OK cout << ans.val() << '\n'; return 0; }