2020.5.26 习题训练三

Posted ccccrack

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2020.5.26 习题训练三相关的知识,希望对你有一定的参考价值。

A - Sorted Adjacent Differences

题意:给出一个长度为n的序列,要求将序列排序,使每两个数之差的绝对值按升序排列

做法:思维题,先sort排序,从中间开始取,往两边推,各取一个,排出来自然满足条件

代码:

//去吧马里奥!把AC公主救回来!
//        ********
//       ************
//       ####....#.
//     #..###.....##....
//     ###.......######
//        ...........
//       ##*#######
//    ####*******######
//   ...#***.****.*###....
//   ....**********##.....
//   ....****    *****....
//     ####        ####
//   ######        ######
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<string>
#include<map>
#include<sstream>
#include<cstring>
#include<vector>
#include<iomanip>
#include<queue>
#include<set>
#define LL long long
#define _64 __int64
const double PI = atan(1.)*4.;
using namespace std;

int a[200005];

int main(){
    int t;
    cin >> t;
    while(t--){
        int n;
        cin >> n;
        for(int i = 0;i < n;i++){
            cin >> a[i];
        }

        sort(a,a+n);

        int num = 0;

        for(int i = n/2-1,j = i+1;i >= 0;i--,j++){
            cout << a[j] << " " << a[i] << " ";

        }

        if(n % 2 != 0){
            cout << a[n-1];
        }
        cout << endl;
    }
}

B - Powered Addition

题意:给一串数列,规定第x秒可以使序列中任意的数增加2^x-1,求最少用几秒使其变成一个升序的序列

做法:关键是可以在随意位置加2^x-1,所以只需要找出这个序列中前面的数和后面的数递减的最大差,之后列方程

2^1+……+2^x-1 >= 最大差求x即可

代码:

//去吧马里奥!把AC公主救回来!
//        ********
//       ************
//       ####....#.
//     #..###.....##....
//     ###.......######
//        ...........
//       ##*#######
//    ####*******######
//   ...#***.****.*###....
//   ....**********##.....
//   ....****    *****....
//     ####        ####
//   ######        ######
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<string>
#include<map>
#include<sstream>
#include<cstring>
#include<vector>
#include<iomanip>
#include<queue>
#include<set>
#define LL long long
#define _64 __int64
const double PI = atan(1.)*4.;
using namespace std;

LL a[200005];

int main(){
    int t;
    cin >> t;
    while(t--){
        int n;
        cin >> n;
        LL k = 0,r = 0;
        cin >> a[0];
        LL pi = a[0];
        for(int i = 1;i < n; i++){
            cin >> a[i];
            pi = max(pi,a[i]);
            if(pi>a[i]){
                r = max(r,pi-a[i]);
            }
        }
        LL j = 1,res = 0;
        while(r > 0){
            r -= j;
            j *= 2;
            res++;
        }
        cout << res << endl;
    }

}

C - Middle Class

题意:给出一个序列和底线值,可以从序列中任意几个数相加,再使其变为平均数,求这样操作之后最多可以有几个超越底线值

做法:将序列排序后,从后面开始往前求和,之后将和减去x,再往前求,再减x,直到求的和小于x为止

代码:

//去吧马里奥!把AC公主救回来!
//        ********
//       ************
//       ####....#.
//     #..###.....##....
//     ###.......######
//        ...........
//       ##*#######
//    ####*******######
//   ...#***.****.*###....
//   ....**********##.....
//   ....****    *****....
//     ####        ####
//   ######        ######
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<string>
#include<map>
#include<sstream>
#include<cstring>
#include<vector>
#include<iomanip>
#include<queue>
#include<set>
#define LL long long
#define _64 __int64
const double PI = atan(1.)*4.;
using namespace std;

int a[200005];

int main(){
     int t;
     cin >> t;
     while(t--){
        int n,x;
        cin >> n >> x;
        for(int i = 0;i < n;i++){
            cin >> a[i];
        }

        sort(a,a+n);
        int ans = 0;
        LL sum = 0;

        for(int i = n - 1;i >= 0;i--){
            if(sum + a[i] - x >= 0){
                sum = sum + a[i] - x;
                ans++;
            }else{
                break;
            }
        }

        cout << ans << endl;
     }
}

D - Circle of Monsters

题意:一群怪物围成环,之后射击怪物,每次减一滴血,如果这个怪物死了,就会爆炸并以两倍的伤害炸伤下一个怪物,求最少射击的次数

做法:想要射击的最少就像玩祖玛一样,要充分利用爆炸伤害,关键是要选一个起点,这个起点的要求就是要是要收到来自上一个爆炸伤害最低的那个怪,也就是最难被炸死的,只要这个被我们打死了,剩下的就可以产生最大的爆炸伤害

所以计算子弹的公式就是

怪物的总血量-爆炸产生的总伤害+爆炸伤害最小的爆炸伤害(因为接受这次伤害的怪物被第一只打死了)

代码:

//去吧马里奥!把AC公主救回来!
//        ********
//       ************
//       ####....#.
//     #..###.....##....
//     ###.......######
//        ...........
//       ##*#######
//    ####*******######
//   ...#***.****.*###....
//   ....**********##.....
//   ....****    *****....
//     ####        ####
//   ######        ######
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<string>
#include<map>
#include<sstream>
#include<cstring>
#include<vector>
#include<iomanip>
#include<queue>
#include<set>
#define LL long long
#define _64 __int64
const double PI = atan(1.)*4.;
using namespace std;

LL a[300005],b[300005];
LL c[300005];

int main(){
    int t;
    cin >> t;
    while(t--){
        int n;
        cin >> n;
        LL sum = 0;
        for(int i = 0;i < n;i++){
            scanf("%lld %lld",&a[i],&b[i]);
            sum += a[i];
        }

        LL ans = 1e18;
        LL ex = 0;

        for(int i = 0;i < n-1;i++){
            c[i] = min(b[i],a[i+1]);
            ex += c[i];
            ans = min(ans,c[i]);
        }

        c[n-1] = min(b[n-1],a[0]);
        ans = min(ans,c[n-1]);
        ex += c[n-1];
        cout << sum - ex + ans << endl;


    }
}

E - Kind Anton

题意:给出两个序列,一个a只包含{1,-1,0},一个b含整数,问是否可以通过使a中一个数加上它前面任何数使a变成b

做法:首先需要标记,一旦前面有1或者-1了就行,之后从后往前循环,a>b就-1,a<b就+1,如果有一个不行就break

代码:

//去吧马里奥!把AC公主救回来!
//        ********
//       ************
//       ####....#.
//     #..###.....##....
//     ###.......######
//        ...........
//       ##*#######
//    ####*******######
//   ...#***.****.*###....
//   ....**********##.....
//   ....****    *****....
//     ####        ####
//   ######        ######
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<string>
#include<map>
#include<sstream>
#include<cstring>
#include<vector>
#include<iomanip>
#include<queue>
#include<set>
#define LL long long
#define _64 __int64
const double PI = atan(1.)*4.;
using namespace std;

int a[200005],b[200005];
int vis1[200005],vis2[200005];

int main(){
    int t;
    cin >> t;
    while(t--){
        int n;
        cin >> n;
        int flag1 = 0,flag2 = 0;
        memset(vis1,0,sizeof(vis1));
        memset(vis2,0,sizeof(vis2));
        for(int i = 0;i < n;i++){
            cin >> a[i];
            if(flag1 == 1){
                vis1[i] = 1;
            }
            if(flag2 == 1){
                vis2[i] = 1;
            }

            if(a[i] == 1){
                flag1 = 1;
            }else if(a[i] == -1){
                flag2 = 1;
            }
        }
        for(int i = 0;i < n;i++){
            cin >> b[i];
        }

        int flag = 0;

            for(int i = n-1;i >= 0;i--){
                flag = 0;
                if(a[i] > b[i]){
                    if(vis2[i] == 1){
                        flag = 1;
                    }
                }
                else if(a[i] < b[i]){
                    if(vis1[i] == 1){
                        flag = 1;
                    }
                }
                else if(a[i] == b[i]){
                    flag = 1;
                }
                if(flag == 0){
                    cout << "NO" << endl;
                    break;
                }

            }

            if(flag == 1){
                cout << "YES" << endl;
            }


    }
}

至于f………………看了题解半天也没看明白什么意思,与其直接复制代码还不如等大佬讲题……

以上是关于2020.5.26 习题训练三的主要内容,如果未能解决你的问题,请参考以下文章

验证码逆向专栏极验三代四代点选类验证码逆向分析

C++项目三代码参考(改进版)

日常Geetest滑动验证码(三代canvas版)处理小结(以B站登录验证为例)

菜鸟学Python训练营第一期练习题

2020-05-22 习题训练二

2020-05-22 习题训练二