1 条题解

  • 0
    @ 2026-11-1 19:56:15

    车的放置(Placing Rooks) 题解

    思路分析

    将 L 形棋盘按水平线切分为上方的 a×ba \times b 矩形(宽 aa 列、高 bb 行)和下方的 (a+c)×d(a + c) \times d 矩形(宽 a+ca + c 列、高 dd 行)。枚举上方矩形放置 ii 个车(0≤i≤k0 \le i \le k):

    1. 在上方选 ii 行 ii 列并排列配对,方案数为 Cbi⋅Cai⋅i!\mathrm{C}_b^i \cdot \mathrm{C}_a^i \cdot i!;
    2. 下方需放 k−ik - i 个车,此时上方用掉的 ii 列不能再放,故下方剩余可用列数为 a+c−ia + c - i,方案数为 $\mathrm{C}_d^{k-i} \cdot \mathrm{C}_{a+c-i}^{k-i} \cdot (k - i)!$。 对所有合法的 ii 求和并对质数 100003100003 取模即可。预处理阶乘与组合数后时间复杂度 O(N2)O(N^2) 或 O(N)O(N)。

    参考代码

    #include <algorithm>
    #include <iostream>
    using namespace std;
    
    const int MOD = 100003;
    const int MX = 2005;
    int C[MX][MX];
    int fact[MX];
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int a, b, c, d, k;
        if (!(cin >> a >> b >> c >> d >> k)) return 0;
    
        for (int n = 0; n < MX; ++n)
        {
            C[n][0] = 1;
            for (int r = 1; r <= n; ++r)
                C[n][r] = (C[n - 1][r - 1] + C[n - 1][r]) % MOD;
        }
        fact[0] = 1;
        for (int i = 1; i < MX; ++i) fact[i] = (1LL * fact[i - 1] * i) % MOD;
    
        long long ans = 0;
        for (int i = 0; i <= k; ++i)
        {
            if (i > a || i > b) continue;
            int rem = k - i;
            if (rem > d || rem > a + c - i) continue;
            long long topWays = 1LL * C[b][i] * C[a][i] % MOD * fact[i] % MOD;
            long long botWays = 1LL * C[d][rem] * C[a + c - i][rem] % MOD * fact[rem] % MOD;
            ans = (ans + topWays * botWays) % MOD;
        }
        cout << ans << "\n";
        return 0;
    }
    
    • 1

    信息

    ID
    8569
    时间
    1000ms
    内存
    128MiB
    难度
    (无)
    标签
    递交数
    0
    已通过
    0
    上传者