• Codeforces Round #733 (Div. 1 + Div. 2) C. Pursuit


    C. Pursuit

    题意

    给t组样例
    每组样例给n个数
    a[1] , a[2] , a[3] ...... a[n]
    b[1] , b[2] , b[3] ...... b[n]
    数据保证(0 <= a[i] , b[i] <= 100 , t组样例n的总和小于1e5)
    a[i]表示第一个人在i这个阶段的分数
    b[i]表示第二个人在i这个阶段的分数
    
    现在只给了n个阶段每个人的分数
    后面若干个阶段的分数值0到100之间都有可能
    
    现在定义一个人在i这个阶段的得分为
    从i个分数中取出 i - i / 4 个最大的分数相加即为
    在i阶段的分数
    
    问在n这个阶段是否第一个人的得分大于第二个人的得分
    如果可以输出0
    如果不行输出最少加几个阶段
    使得第一个人的得分大于等于第二个人的得分
    

    思路

    既然要让a的分数要大于等于b的分数
    
    那么a[n+1] , a[n+2] , a[n+3] ......都应该是100
    b[n+1] , b[n+2] , b[n+3] ....... 都应该是0
    
    所以从大到小排序之后
    用前缀和优化到on
    on枚举o1判断即可 
    

    时间复杂度:O n

    #include<bits/stdc++.h>
    #define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
    #define re register int
    #define pll pair<int,int> 
    #define x first 
    #define y second 
    #define sf(x) scanf("%d",&x)
    #define sfl(x) scanf("%lld",&x)
    typedef long long ll ;
    using namespace std;
    const int N =  1e6 + 10 , M = 2010 , inf = 0x3f3f3f3f , mod = 1e9 + 7 ;
    int t ;
    int n ;
    int a[N] , b[N] ;
    int s[N] , h[N] ;
    int main()
    {
        cin >> t ;
        while(t--)
        {
            cin >> n ;
            
            fer(i,1,n) 
            {
                sf(a[i]) ;
            }
            
            fer(i,1,n)
            {
                sf(b[i]) ;
            }
            
            sort(a + 1 , a + 1 + n) ;
            sort(b + 1 , b + 1 + n) ;
            reverse(a + 1 , a + 1 + n) ;
            reverse(b + 1 , b + 1 + n) ;
            
            fer(i,1,n) 
            {
                s[i] = s[i-1] + a[i] ;
            }
            
            fer(i,1,n)
            {
                h[i] = h[i-1] + b[i] ;
            }
            
            fer(i,n+1,3e5)
            {
                s[i] = s[i-1] + 100 ;
            }
            
            fer(i,n+1,3e5)
            {
                h[i] = h[i-1] ;
            }
            
            if(s[n-n/4] >= h[n-n/4])
            {
                puts("0") ;
            }
            else
            {
                for(int i = n + 1 ; i <= N ; i ++)
                {
                    int j = i - i / 4 ;
                    // j为取多少个最大的个数
                    int z = i - n ;
                    // z为有多少个多余的100可以取
                    
                    int s1 , s2 ;
                    if(z <= j) s1 = 100 * z + s[j-z] ;
                    else s1 = 100 * j ;
                    
                    s2 = h[j] ;
                    if(s1 >= s2)
                    {
                        cout << i - n << "
    " ;
                        break ;
                    }
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    解决VM 安装Ubuntu64与 Device/Credential Guard 不兼容,显示不支持64位系统
    WPF处理内容溢出
    .NET Standard 2.0 是什麼?可以吃嗎?
    C#.Net]启动外部程序的几种常用方法汇总
    在C#中接收系统屏幕锁定和解锁的事件
    C#.Net]启动外部程序的几种常用方法汇总
    MongoDB索引的使用
    读取xml并将节点保存到Excal
    开学后的第一篇
    续并查集学习笔记——Gang团伙题解
  • 原文地址:https://www.cnblogs.com/yueshehanjiang/p/15026232.html
Copyright © 2020-2023  润新知