• HDU-5719 Arrange


    Arrange

     
     Accepts: 221
     
     Submissions: 1401
     Time Limit: 8000/4000 MS (Java/Others)
     
     Memory Limit: 262144/262144 K (Java/Others)
    问题描述
    Cupid一不小心将爱情之箭射到了自己,他爱上了Psyche。
    
    这引起了他的母亲Venus的注意。Venus将Psyche带到了一堆打乱的谷堆旁。
    
    这儿共有nn堆稻谷,编号为11nn。Psyche需要将这些谷堆以某种顺序排列,设最终排在第ii位的谷堆是A_iAi。
    
    她得知了一些该排列的要求:
    
      1. 对于任意整数i in [1,n]i[1,n]A_1, A_2, ..., A_iA1,A2,...,Ai的最小值为B_iBi。
    
      2. 对于任意整数i in [1,n]i[1,n]A_1, A_2, ..., A_iA1,A2,...,Ai的最大值为C_iCi。
    
    现在Psyche想知道,共有多少种合法的排列。由于答案可能很大,输出时对998244353998244353取模。
    输入描述
    第一行,一个整数TT (1 le T le 15)(1T15),代表数据组数。
    
    对于每组数据,第一行有一个整数nn (1 le n le 10 ^ 5)(1n105),代表排列大小。
    
    第二行,nn个整数,第ii个整数为B_iBi (1 le B_i le n)(1Bin)。
    
    第三行,nn个整数,第ii个整数为C_iCi (1 le C_i le n)(1Cin)
    输出描述
    输出TT行,对于每组数据输出答案对998244353998244353取模的结果。
    输入样例
    2
    3
    2 1 1
    2 2 3
    5
    5 4 3 2 1
    1 2 3 4 5
    输出样例
    1
    0
    Hint
    对于第一组数据,只有一种合法的排列(2,1,3)(2,1,3)。
    
    对于第二组数据,没有合法的排列。

    解题思路:

    这道题有很多的点需要小心

    总体来说,就两个点,一个是判断有无解,一个是计算解的个数

    求解解的个数就是直接类似全排列的方式求就行,这个并不难。主要是判断有无解。

    无解的情况有:

    1.b[0]和c[0]不相等

    2.b[i]比c[i]大

    3.b序列不是单调非升序

    4.c序列不是单调非降序

    5.在第i个位置时没有可以放在这个位置的元素


    代码如下:

    #include <cstdio>
    #include <cstring>
    using namespace std;
    #define mod 998244353
    #define INF 0x3f3f3f3f
    typedef long long LL;
    const int maxn = 1e5 + 5;
    int a[maxn], b[maxn];
    int main()
    {
        // freopen("test.in", "r+", stdin);
        // freopen("test.out", "w+", stdout);
        int t, n;
        scanf("%d", &t);
        while(t--){
            scanf("%d", &n);
            for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
            for(int i = 1; i <= n; ++i) scanf("%d", &b[i]);
            a[0] = INF; b[0] = -1;
    
            LL ans = 1;
            for(int i = 1; i <= n; ++i){
                if(i == 1 && a[i] != b[i]){
                    ans = 0;
                    break;
                }
                if(a[i] > a[i-1]) {
                    ans = 0;
                    break;
                }
                if(b[i] < b[i-1]){
                    ans = 0;
                    break;
                }
                if(b[i] < a[i]){
                    ans = 0;
                    break;
                }
                if(i != 1 && a[i] < a[i-1] && b[i] > b[i-1]){
                    ans = 0;
                    break;
                }
    
                if(a[i] == a[i-1] && b[i] == b[i-1]){
                    if(b[i] - a[i] + 2 - i <= 0) {
                        ans = 0;
                        break;
                    }
                    ans = (ans * (b[i] - a[i] + 2 - i)) % mod;
                }
            }
    
            printf("%lld
    ", ans);
        }
        return 0;
    }


  • 相关阅读:
    python如何打开一个大文件?
    python中的多进程与多线程(二)
    python中的多进程与多线程(一)
    python中的深拷贝与浅拷贝
    2018 pycharm最近激活码
    python中的新式类与旧式类
    用python优雅打开文件及上下文管理协议
    解决Mac上安装mysqlclient的错误
    用python实现一个简单的服务器
    高阶函数
  • 原文地址:https://www.cnblogs.com/wiklvrain/p/8179460.html
Copyright © 2020-2023  润新知