题解 | #B Problem#

小L的三角尺

https://ac.nowcoder.com/acm/contest/120566/A

解题思路:

如果把n个球排成一排不动,我们只要考虑左右盒子放在哪里,用的是数学里面的隔板法

1 2 3 4 5 6 7 8 8

L L|R R R |L L L

|代表就是t,那么t为奇数时候,就会分成偶数块,如果是偶数时候,就会分成奇数块,那么我们将分类讨论是L的多一个还是R多一个,下面是代码(用到了组合数)

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ios ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define endl '\n'

const int mod = 998244353;
const int N = 1000005;

int fac[N], inv[N]; // 存放阶乘和阶乘的逆元
// 快速幂
int power(int a, int b)
{
    int res = 1;
    while (b > 0)
    {
        if (b % 2 == 1)
        {
            res = res * a % mod;
        }
        a = a * a % mod;
        b /= 2;
    }
    return res;
}
// 预处理:在程序刚开始的时候将所有的阶乘算好
void pre()
{
    fac[0] = 1;
    for (int i = 1; i < N; i++)
    {
        fac[i] = fac[i - 1] * i % mod;
    }
    // 用费马小定理算逆元
    inv[N - 1] = power(fac[N - 1], mod - 2);
    for (int i = N - 2; i >= 0; i--)
    {
        inv[i] = inv[i + 1] * (i + 1) % mod;
    }
}
// 计算组合数
int ncr(int n, int k)
{
    if (k < 0 || k > n)
        return 0;
    return fac[n] * inv[k] % mod * inv[n - k] % mod;
}

void solve()
{
    int n, x, t;
    cin >> n >> x >> t;
    //特判: 如果球全在一个盒子里的
    if (x == 0 || x == n)
    {
        if (t == 0)
            cout << 1 << endl;
        else
            cout << 0 << endl;
        return;
    }
    //t是奇数的话,分为4块
    if (t % 2 == 1)
    {
        int m = (t + 1) / 2;//左右各有m块
        int ans = 2 * ncr(x - 1, m - 1) % mod * ncr(n - x - 1, m - 1) % mod;
        cout << ans << endl;
    }
    else
    {//块数为奇数
        int m = t / 2;
        //可能L比R多一块
        int sum1 = ncr(x - 1, m) * ncr(n - x - 1, m - 1) % mod;
        //可能R比L多一块
        int sum2 = ncr(n - x - 1, m) * ncr(x - 1, m - 1) % mod;
        cout << (sum1 + sum2) % mod << endl;
    }
}

signed main()
{
    ios;
    int T;
    pre();
    cin >> T;
    while (T--)
    {
        solve();
    }
    return 0;
}
全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务