Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /// Имеется прямоугольное поле размера `n \times m`. Нужно посчитать число способов замостить его
- /// доминошками размера `1 \times 2`. Доминошки могут быть повернуты горизонтально или вертикально,
- /// но они не должны перекрываться или выходить за пределы поля. Поскольку ответ может быть
- /// достаточно большим, требуется вывести его по модулю `k` (остаток от деления ответа на `k`).
- pub fn solve() {
- let m: u32 = 16;
- let n: u32 = 16;
- let bound: u64 = 1_000_000_000;
- let mut d = vec![0u64; 2_u32.pow(m) as usize];
- d[0] = 1;
- // optimized to the left shifts
- let pow2_m2 = 2_u32.pow(m - 2);
- let pow2_m1 = 2_u32.pow(m - 1);
- for _ in 0..n {
- for i in 0..m - 1 {
- for k in 0..pow2_m2 {
- let k0 = insert_00(i, k);
- let t = 1 << i;
- let k1 = k0 + t;
- let k2 = k1 + t;
- let k3 = k2 + t;
- d.swap(k0, k1);
- d.swap(k2, k3);
- d[k2] += d[k1];
- d[k2] %= bound;
- }
- }
- for k in 0..pow2_m1 {
- let k0 = k as usize;
- let k1 = k0 + pow2_m1 as usize;
- d.swap(k0, k1);
- }
- }
- println!("m = {}, n = {}, d = {}", m, n, d[0]);
- }
- /// функция вставляет два нулевых бита в позицию i,
- /// пример для k == 63 и i == 0, 1, ... , 6
- /// 11111100
- /// 11111001
- /// 11110011
- /// 11100111
- /// 11001111
- /// 10011111
- /// 00111111
- fn insert_00(i: u32, k: u32) -> usize {
- let mut x = k.clone();
- let mut y = k.clone();
- x <<= 2;
- x &= (3_u32 << i).not();
- x &= 0_u32.not() << i;
- y &= (0_u32.not() << i).not();
- x |= y;
- x as usize
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement