zoukankan      html  css  js  c++  java
  • Codeforces Round #726 (Div. 2) A B C D E1 题解

    A. Arithmetic Array

    题意

    给你n个数的数组
    问最多加几个非负数
    可以让数组总和/元素个数等于1
    

    思路

    分类讨论
    假设总和为sum,数组个数为n
    假设加了cnt个非负数x
    目标是 sum + cnt * x = n + cnt
    这个式子不难发现右边每次只可以加1
    左边可以加任何非负数
    所以
    如果sum = n  答案为0
    如果sum < n  答案为1
    如果sum > n  
    因为右边每次只能加1
    左边x可以为0
    等价于 sum = n + cnt 
    所以答案为 sum - n
    

    时间复杂度: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 = 1010 , inf = 0x3f3f3f3f , mod = 1e9 + 7 ;
    int t ;
    int n ;
    int a[N] ;
    int main()
    {
        cin >> t ;
        while(t--)
        {
            cin >> n ;
            
            int sum = 0 , res = 0 ;
            fer(i,1,n)
            {
                cin >> a[i] ;
                if(a[i] > 0) sum += a[i] ;
                else if(a[i] < 0) res += a[i] ;
            }
            
            if(sum + res == n) puts("0") ;
            else if(sum + res < n) puts("1") ;
            else
            {
                cout << sum + res - n << "
    " ;
            }
        }
        return 0;
    }
    

    B. Bad Boy

    题意

    一个n*m的地图,一个人一开始在sx,sy这个位置
    问如何安排2个溜溜球的位置,
    使得他所走的距离最大化
    并且要拿起这2个溜溜球
    最后回到起点sx,sy这个位置
    

    思路

    因为只能上下左右走
    所以距离是曼哈顿距离
    并且如果距离要最大
    肯定是把这2个溜溜球放在4个端点的其中2个
    {{1,1},{1,m},{n,1},{n,m}}
    所以枚举这2个端点
    求出最大值即可
    后面发现1,1,n,m一定是最优解
    所以直接输出即可
    

    时间复杂度: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 = 1010 , inf = 0x3f3f3f3f , mod = 1e9 + 7 ;
    int t ;
    int n , m , sx , sy ;
    int main()
    {
        cin >> t ;
        while(t--)
        {
            cin >> n >> m >> sx >> sy ;
            
            cout << 1 << " " << 1 << " " << n << " " << m << "
    " ;
        }
        return 0;
    }
    

    C. Challenging Cliffs

    题意

    给n个数的数组h[n]
    可以按任意顺序排序
    求当abs(h[1]-h[n])最小的时候
    h[i] <= h[i+1]的i的个数最大
    (1 <= i <= n - 1)
    

    思路

    贪心
    首先从小到大排序之后
    首先找到2个下标sx,sy
    使得abs(h[sx]-h[sy])最小
    可以发现
    1 <= i < sx h[i] <= h[i+1]
    sy <= i < n  h[i] <= h[i+1] 
    所以把sy到n中的数放前面
    把1到sx中的数放后面
    当h[1]!=h[n]的时候
    h[i] <= h[i+1]的i的个数最大为n-2
    当h[1]==h[n]的时候 为n-1
    

    时间复杂度:O tnlogn

    #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 = 1010 , inf = 0x3f3f3f3f , mod = 1e9 + 7 ;
    int t ;
    int n ;
    int a[N] ;
    int main()
    {
        cin >> t ;
        while(t--)
        {
            cin >> n ;
            
            fer(i,1,n) sf(a[i]) ;
            
            sort(a + 1 , a + 1 + n) ;
            
            int res = 1e9 ;
            
            fer(i,2,n)
            {
                res = min(res,a[i] - a[i-1]) ;
            }
            
            int sx , sy ;
    
            fer(i,2,n)
            {
                if(a[i] - a[i-1] == res)
                {
                    sx = i - 1 ;
                    sy = i ;
                    break ;
                }
            }
            
            //cout << res << "
    " ;
            //cout << sx << " " << sy << "
    " ;
            
            if(n >= 3)
            {
                for(int i = sy ; i <= n ; i ++)
                {
                    cout << a[i] << " " ;
                }
                
                for(int i = 1 ; i <= sx ; i ++)
                {
                    cout << a[i] << " " ;
                }
            }
            else if(n == 2)
            {
                for(int i = 1 ; i <= n ; i ++)
                    cout << a[i] << " " ;
            }
            cout << "
    " ;
        }
        return 0;
    }
    

    D. Deleting Divisors

    题意

    给定n
    每次可以进行一个操作
    减去这个数的其中一个因数
    这个因数不能是1和他本身
    Alice先手
    谁最后不能操作就输
    问谁赢
    

    思路

    结论:n是奇数或者2的奇数次幂Bob赢,否则alice赢
    引用幽灵抽风大神的证明:
    先假设对于偶数和奇数的那个性质成立
    若n是2的幂次,那么每次只能减2的幂次
    如果减完不是2的幂次就输了
    所以每次一定减2的幂次
    换句话说,如果n=2^k,那么减完了n=2^{k-1}
    当n是2的时候Bob赢
    所以2的奇次幂Bob赢,偶次幂Alice赢
    然后如果n不是2的幂,且n是奇数
    那么n的所有因子都是奇数
    所以n要变成的数一定是偶数
    反之如果n是偶数且不是2的幂
    则n有奇数因子,那么n就可以变成奇数
    所以n是奇数则Bob赢,否则Alice赢
    

    时间复杂度: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 = 1010 , inf = 0x3f3f3f3f , mod = 1e9 + 7 ;
    
    int main()
    {
        unordered_map<ll,bool> q ;
        q[0] = 1 ;
        
        for(ll i = 1 ; i <= 31 ; i += 2)
        {
            q[1 << i] = true ;
        }
        
        int t ;
        cin >> t ;
        
        while(t--)
        {
            ll n ;
            cin >> n ;
            if(n & 1 || q[n]) puts("Bob");
            else puts("Alice");
        }
        return 0;
    }
    

    E1. Erase and Extend (Easy Version)

    题意

    给定n,k,和一个字符串s
    2个操作
    1是s = s + s 
    2是删除s的最后一个字符
    每个操作可以进行任意次
    求经过任意次操作且长度为k的且字典序最小的字符串
    1 <= n,k <= 5000
    

    思路

    考虑n,k的范围
    可以暴力n^2做
    不管最后怎么进行操作
    长度为k的字符串只有n种情况
    因为最后的字符串长度如果大于k了
    你可以减到k
    所以暴力求出这n个字符串
    sort排序一下
    输出第一个即可
    

    时间复杂度:O n^2

    #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 = 1010 , inf = 0x3f3f3f3f , mod = 1e9 + 7 ;
    char a[N] ;
    int b[N] ;
    int z = 0 ;
    string q[N] ;
    int main()
    {
        int n , k ;
        
        cin >> n >> k ;
        
        cin >> a + 1 ;
        
        int c = 0 ;
        
        for(int i = 1 ; i <= n ; i ++)
        {
            string x = "" ;
            for(int j = 1 ; j <= i ; j ++)
            {
                x += a[j] ;
            }
            
            string y = "" ;
            
            for(int j = 1 ; j <= k / i + 5 ; j ++)
            {
                y += x ;
            }
            
            q[++ c] = y.substr(0,k) ;
            //cout << y.substr(0,k) << "
    " ;
            // cout << y << "
    " ;
        }
        
        sort(q + 1 , q + 1 + c) ;
        
        cout << q[1] << "
    " ;
        return 0;
    }
    
  • 相关阅读:
    etcd:从应用场景到实现原理的全方位解读
    open-falcon编写的整个脑洞历程
    开源还是商用?十大云运维监控工具横评
    我的后端开发书架2015 2.0版
    【MDCC 2015】友盟数据平台负责人吴磊:移动大数据平台的架构与实践
    Effective Go
    Airbnb JavaScript Style Guide
    Google HTML/CSS Style Guide
    nservicebus教程-目录
    测试
  • 原文地址:https://www.cnblogs.com/yueshehanjiang/p/14901802.html
Copyright © 2011-2022 走看看