zoukankan      html  css  js  c++  java
  • 2020-05-18 — 习题训练一题解

    A.Phoenix and Balance

    题意:给一组数2^1,2^2,……,2^n,然后平均分为两组,使其两组和的差绝对值最小

    注意到2 ^ (n+1) = 2^0 + ... 2 ^n +1;

    所以 a[n] = a[0] + .. a[n-1] + 2;

    含a[n]的一方尽可能选小的就可

    #include <iostream>
    #include <cstdio>
    using namespace std;
    int n, a[32];
    int q_pow(int n)
    {
        int a = 2, res = 1;
        while(n)
        {
            if(n & 1) res *= a;
            a *= a;
            n >>= 1;
        }
        return res;
    }
    int t;
    int main()
    {
        cin >> t;
        a[1] = 2;
        for(int i = 2;i <= 30; ++ i) a[i] = 2 * a[i-1];
        while(t--)
        {
            int res = 0;
            cin >> n;
            res = a[n];
            int num = 1;
            for(int i = 1;i <= n; ++ i)
            {
                if(num == n/2){
                    for(int j = i;j <= n-1; ++ j)
                    res -= a[j];
                    break;
                }
                else{
                    res += a[i];
                    num ++;
                }
            }
            cout << res << endl;
        }
    
    //    a[n] = a[1] + ... a[n-1] - 1;
    //    a[n] + a[1] + ... a[m]  = 
    }

    B.Phoenix and Beauty

    题意:给出n个数,通过进行增加新的数字(数字必须在1-n之间)使得数列周期为k, 并输出长度, 若弄不了,输出-1

    当 k < n个数中不同的数时,输出-1吧,return 0;

    扫一遍数组,遇到数就把所有的数都输出一遍,不够k个数随便添个数,凑够k个数,周期就是k了,长度不会超给定的范围

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <set>
    using namespace std;
    int n, a[6666], k, t, b[6666];
    int main()
    {
        cin >> t;
        while(t--)
        {
            memset(b, 0, sizeof(0));
            cin >> n >> k;
            int cnt = 0;
            for(int i = 1;i <= n; ++ i)
            {
                cin >> a[i];
                int flag = 1;
                for(int j = 1;j <= cnt; ++ j) 
                if(b[j] == a[i]) flag = 0;
                if(flag)
                b[++cnt] = a[i];
            }    
            sort(b + 1, b + 1 + cnt);
            if(k < cnt){
                cout << "-1" << endl;
                continue;
            }
            cout << n * k << endl;
            for(int i = 1;i <= n; ++ i)
            {
                for(int j = 1;j <= cnt; ++ j) cout << b[j] << " ";
                int j = k - cnt;
                while(j)
                {
                    cout << b[cnt] << " ";
                    j --;
                }
            }
            cout << endl;
        }
    }

    C.Road To Zero

    题意:有两个数x,y,其中一个数增1或减1的话,需要花费a元,如果两个数一起减1或加1的话,需要花费b元,询问xy都变为0时花费的最少钱

    分情况讨论

    #include <iostream>
    using namespace std;
    typedef long long LL;
    LL t, x, y, a, b;
    int main()
    {
        cin >> t;
        while(t--)
        {
            cin >> x >> y >> a >> b;
            LL minn = min(x, y), maxn = max(x, y);
            LL sum = x + y;
            LL ans = sum * a <= (minn * b + (maxn - minn) * a) ? sum * a :(minn * b + (maxn - minn) * a);
            cout << ans << endl;
        }
    }

    D.Binary Period

    题意:给出01组成的字符串,进行寻找新的数组,并且已知数组可以通过对新数组的某个位置的数进行删除得到,并且使其是循环数组,循环的部分长度最短,总长度不超过2n

    只有一个数时,周期为1,有两种数时由于 max_lenth <= 2n 循环输出01即可,子序列一定有原字符串

    /*00 
    0101
    110   1010
    11110 10101010
    00001 01010101
    */
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    char s[666];
    int t;
    int main()
    {
        cin >> t;
        while(t--)
        {
            int num0 = 0, num1 = 0;
            memset(s, 0, sizeof(s));
            cin >> s;
            for(int i = 0;i < strlen(s); ++ i)
            if(s[i] == '0') num0 ++;
            else num1++;
            if(num0 == 0 || num1 == 0){
                cout << s << endl;
                continue;
            }
            for(int i = 1;i <= strlen(s); ++ i)
            {
                cout << "0" << "1";
            }
            cout << endl;
        }
    

    E.Nastay and Rice

    题目:一共五个数n,a,b,c,d,计算(a-b)~(a+b),是否可以通过乘以n和(c-d)~(c+d)有交集 

    分情况讨论就可

    #include <iostream>
    #include <cmath>
    using namespace std;
    int t, n, a, b, c, d;
    int main()
    {
        cin >> t;
        while(t--)
        {
            cin >> n;
            cin >> a >> b >> c >> d;
            int s = abs(a-b), e = a + b;
            if(s * n > c + d || e * n < abs(c-d)) cout << "NO" << endl;
            else cout << "YES" << endl; 
        }
    
    }

    F.Nastay and Door

    题意:给你n,k,n个山峰值,山峰巅峰值就是这座山峰值比其他的都高,问在k个相连续的山峰中,山峰巅峰值个数是多少,并且这k个连续山峰中最左边的山峰坐标是多少

    a[n] = 1, 2, 3 , 2, 4, 3
    b[n] = 0, 0, 1, 1, 2, 2;
    b[i-1] - b[i-k+1] 表示从i-k+1 到 i 中峰的个数
    if(res < b[i-1] - b[i-k+1]) 就更新 res 和“答案”下标
    #include <iostream>
    using namespace std;
    const int N = 2e5 + 10;
    int t, n, k, a[N], b[N];
    int main()
    {
        cin >> t;
        while(t--)
        {
            cin >> n >> k;
            for(int i = 1;i <= n; ++ i) cin >> a[i];
            int res = 0, flag = 1;
            for(int i = 2;i <= n; ++ i)
            {
                if(i != n && a[i] > a[i+1] && a[i] > a[i-1])
                b[i] = b[i-1] + 1;
                else b[i] = b[i-1];
                
                if(i >= k && b[i-1] - b[i-k+1] > res)
                res = b[i-1] - b[i-k+1], flag = i-k+1;
            }
            cout << res + 1 << " " << flag << endl;
        }
    }

     https://vjudge.net/contest/374474#overview

  • 相关阅读:
    Linux进程间通信 --- 管道
    ARM常用汇编指令列表 --- 转自百度文库
    操作Linux系统环境变量的几种方法
    谈谈JAVA程序的反编译
    浅谈Java Virtual Machine
    使用非java代码编程
    java编程中常用英语单词
    linkin大话面向对象--类和对象
    Linkin大话Java和internet概念
    Linkin大话eclipse快捷键
  • 原文地址:https://www.cnblogs.com/DefineWaAc/p/12923800.html
Copyright © 2011-2022 走看看