結果
| 問題 | No.220 世界のなんとか2 |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2026-08-24 17:07:52 |
| 言語 | Rust (1.94.0 + proconio + num + itertools) |
| 結果 |
AC
|
| 実行時間 | 0 ms / 1,000 ms |
| + 866µs | |
| コード長 | 2,446 bytes |
| 記録 | |
| コンパイル時間 | 16,573 ms |
| コンパイル使用メモリ | 187,952 KB |
| 実行使用メモリ | 6,272 KB |
| 最終ジャッジ日時 | 2026-08-24 17:08:16 |
| 合計ジャッジ時間 | 2,799 ms |
|
ジャッジサーバーID (参考情報) |
judge3_0 / judge2_0 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 19 |
ソースコード
use std::{collections::HashMap, hash::Hash};
use proconio::input;
// 0. 決定性有限オートマトン
trait Dfa {
type State;
type Alphabet;
fn init(&self) -> Self::State;
fn next(&self, q: &Self::State, c: &Self::Alphabet) -> Self::State;
fn accept(&self, q: &Self::State) -> bool;
}
// 1. MultipleOf(3) は 3 の倍数を認識するオートマトン
struct MultipleOf(u64);
impl Dfa for MultipleOf {
type State = u64;
type Alphabet = u8;
fn init(&self) -> Self::State {
0
}
fn next(&self, q: &Self::State, c: &Self::Alphabet) -> Self::State {
(q * 10 + (c - b'0') as u64) % self.0
}
fn accept(&self, q: &Self::State) -> bool {
*q == 0
}
}
// 2. Seen(b'3') は 3 がつく数を認識するオートマトン
struct Seen(u8);
impl Dfa for Seen {
type State = bool;
type Alphabet = u8;
fn init(&self) -> Self::State {
false
}
fn next(&self, q: &Self::State, c: &Self::Alphabet) -> Self::State {
*q || *c == self.0
}
fn accept(&self, q: &Self::State) -> bool {
*q
}
}
// 3. Or(a, b) は a または b が認識する数を認識するオートマトン
struct Or<A, B>(A, B);
impl<A: Dfa, B: Dfa<Alphabet = A::Alphabet>> Dfa for Or<A, B> {
type State = (A::State, B::State);
type Alphabet = A::Alphabet;
fn init(&self) -> Self::State {
(self.0.init(), self.1.init())
}
fn next(&self, q: &Self::State, c: &Self::Alphabet) -> Self::State {
(self.0.next(&q.0, c), self.1.next(&q.1, c))
}
fn accept(&self, q: &Self::State) -> bool {
self.0.accept(&q.0) || self.1.accept(&q.1)
}
}
// 4. count(a, Σ, n) は a が認識する言語と Σ^n の共通部分を数える
fn count<A, S>(dfa: A, sigma: S, len: usize) -> u64
where
A: Dfa,
A::State: Eq + Hash,
S: Iterator<Item = A::Alphabet> + Clone,
{
let mut dp = HashMap::new();
dp.insert(dfa.init(), 1);
for _ in 0..len {
let mut ndp = HashMap::new();
for (q, v) in dp {
for c in sigma.clone() {
*ndp.entry(dfa.next(&q, &c)).or_insert(0) += v;
}
}
dp = ndp;
}
dp.iter()
.filter_map(|(q, v)| dfa.accept(q).then_some(v))
.sum()
}
// 5. Just Do It !!!!
fn main() {
input!(p: usize);
let dfa = Or(MultipleOf(3), Seen(b'3'));
println!("{}", count(dfa, b'0'..=b'9', p) - 1);
}