NLinker icon

Задача о замощении домино

NLinker | PRO | 05/10/21 09:05:22 PM UTC | 0 ⭐ | 8386 👁️ | Never ⏰ | []
Rust |

2.03 KB

|

None

|

0 👍

/

0 👎

/// Имеется прямоугольное поле размера `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
}
 

Comments

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎