• CF 1569C Jury Meeting


    C.Jury Meeting

    来源:https://codeforces.com/contest/1569/problem/C
    标签:【组合数】【数学】

    题目简述

    n个人参加聚会,每个人有ai个问题,聚会上大家轮流讲述自己的问题,当前人讲完一个自己的问题后轮到下一位,并且当前人问题数减一。问题讲述完者自动出局。聚会持续到直到所有人讲完问题。询问有多少种排列满足如下条件:
    聚会过程中没有任何一个人能连续讲述自己的两个问题。
    由于方案数过大,对998244353取模。

    Input
    第一行输入测试样例数T(1<=t<=104);
    对于每一个测试样例,第一行输入成员数 n (2<=n<=2*105),接下来一行n个数ai,代表每一个成员的问题数.

    Output
    每一个测试样例输出一个答案。

    Sample Input

    4
    2
    1 2
    3
    5 5 5
    4
    1 3 3 7
    6
    3 4 2 1 3 3
    

    Sample Output

    1
    6
    0
    540
    

    More Info

    对于第一个样例,[1,2]不可行,因为第二位会连续讲述两个自己的问题,[2,1]可行,所以答案为1.
    

    题目思路

    首先要明白一个结论,只有问题最多(>=2)的人排在最后且这样的人只有一位的情况下,才可能出现有人连续讲述两个问题的情况,而这个人就是他自己。
    设最大数为mx,次大数(即最大数-1)为nmx,最大数的个数为mxcnt,次大数的个数为nmxcnt,默认mx>=2。
    (1)当mxcnt>=2的时候,答案为全排列,ans=n!;
    (2)当mxcnt=1且nmxcnt=0的时候,无解,ans=0;
    (3)当mcnt=1且nmxcnt>0的时候,只有所有次大数排在最大数前面的排列不满足要求,因为这样的排列最终都会形成[1,2]的局面,用全排列减去这些排列的数目,就是答案。(也可以参考下面的写法,求把最大数放在所有次大数的后面的排列)

    代码(附注释)

    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define endl '
    ';
    #define ll long long
    const int N=200005;
    const int mod=998244353;
    
    int t,n,a[N];
    
    int main()
    {
        ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
        cin>>t;
        while(t--){
            cin>>n;
            int mx=0,mcnt=0;
            for(int i=1;i<=n;++i) cin>>a[i],mx=max(mx,a[i]);
            for(int i=1;i<=n;++i) if(a[i]==mx) mcnt++;
            int p=1,b=1;
            ll ans=1;
            if(mcnt==1){//最大数数目为1
                mcnt=0;
                for(int i=1;i<=n;++i) if(a[i]==mx-1) mcnt++;
                p=mcnt+1,b=mcnt;
            }
            for(int i=1;i<=n;++i){
                if(i==p) ans=(ans*b)%mod;
                else ans=(ans*i)%mod;
            }
            cout<<ans<<endl;
        }
    
        return 0;
    }
    
  • 相关阅读:
    中级实训Android学习记录——百度地图API显示定位
    中级实训Android学习记录——Android Studio工程配置并进行地图显示
    中级实训Android学习记录——百度地图API获取AK
    unity 3d 八、粒子系统与流动效果
    中级实训Android学习记录——项目3制作
    中级实训Android学习记录——RecyclerView、Android存储
    中级实训Android学习记录——项目1、2重铸记录
    裴蜀定理
    二分模板
    最短路问题
  • 原文地址:https://www.cnblogs.com/unravel-CAT/p/15249628.html
Copyright © 2020-2023  润新知