zoukankan      html  css  js  c++  java
  • [组合数学] Codeforces 1608D Dominoes

    题目大意

    给你 \(n\) 张卡牌,每张卡牌有左边和右边两个格子,可以涂上红色或蓝色。一开始有些格子被涂了颜色,有些没有涂。要求给卡牌的格子涂完色,使得最终可以通过合理安排卡牌的顺序,使得第 \(i\) 张卡牌的右边格子和第 \((i\ \mathrm{mod}\ n)+1\) 张卡牌的左边格子不同色,卡牌不能左右翻转。求涂色方案数模 \(998244353\)

    题解

    首先,蓝色格子的数量和红色格子的数量一定要相同。在满足这一限制的条件下,若同时有一张 WWBB,则剩下卡牌的涂色是任意的,因为无论怎么涂,总能插入WW BB 这个环中。但若没有 WWBB,则只有两种情况,要么全为 WB,要么全为 BW。于是我们可以算出蓝色和红色格子数量相等时任意涂色的方案数,再减去不含有 BBWW 的方案数,再加上全为 WB 或全为 BW 的方案数,即为答案。

    Code

    #include <bits/stdc++.h>
    using namespace std;
    
    #define LL long long
    const LL MOD = 998244353;
    LL inv[200010], fact[200010], finv[200010];
    string s[100010];
    map<string, int> mp;
    int cnt[2];
    int n;
    
    void Init() {
        inv[1] = fact[0] = fact[1] = finv[0] = finv[1] = 1;
        for (int i = 2;i <= 200000;++i) {
            inv[i] = ((-(MOD / i) * inv[MOD % i]) % MOD + MOD) % MOD;
            fact[i] = fact[i - 1] * i % MOD;
            finv[i] = finv[i - 1] * inv[i] % MOD;
        }
    }
    
    LL qpow(LL b, LL n) {
        LL x = 1, Power = b % MOD;
        while (n) {
            if (n & 1) x = x * Power % MOD;
            Power = Power * Power % MOD;
            n >>= 1;
        }
        return x;
    }
    
    int main() {
        Init();
        ios::sync_with_stdio(false);
        cin >> n;
        for (int i = 1;i <= n;++i) { cin >> s[i]; ++mp[s[i]]; }
        for (int i = 1;i <= n;++i) {
            if (s[i][0] == 'W') ++cnt[0];
            else if (s[i][0] == 'B') ++cnt[1];
            if (s[i][1] == 'W') ++cnt[0];
            else if (s[i][1] == 'B') ++cnt[1];
        }
        if (cnt[0] > n || cnt[1] > n) { cout << 0 << endl; return 0; }
        LL ans = fact[n * 2 - cnt[0] - cnt[1]] * finv[n - cnt[0]] % MOD * finv[n - cnt[1]] % MOD;
        if (mp.count("BB") || mp.count("WW")) { cout << ans << endl; return 0; }
        ans = ((ans - qpow(2, mp["??"])) % MOD + MOD) % MOD;
        if (!mp.count("BW") && !mp.count("B?") && !mp.count("?W")) ++ans;
        if (!mp.count("WB") && !mp.count("W?") && !mp.count("?B")) ++ans;
        ans %= MOD;
        cout << ans << endl;
    
        return 0;
    }
    
  • 相关阅读:
    剑指offer面试题17:合并两个排序的链表
    剑指offer面试题16:反转链表
    剑指offer面试题15:链表中倒数第K个节点
    Jinja2.template渲染两种常见用法
    hadoop集群运维碰到的问题汇总
    hbase配置参数总结
    hbase内核学习总结
    zookeeper学习笔记
    mongodb 3.2性能测试
    kafka内部结构笔记
  • 原文地址:https://www.cnblogs.com/AEMShana/p/15767169.html
Copyright © 2011-2022 走看看