首页 > 其他 > 详细

2020.5.18 习题训练一

时间:2020-05-20 22:31:10      阅读:62      评论:0      收藏:0      [点我收藏+]

A - Phoenix and Balance

题意:给出重量为……的n枚硬币,要将其分为两等份,求怎么分,分出来的两堆硬币的重量的绝对值差值最小。

做法:根据规律,最后一个硬币重量一定大于之前所有硬币之和,将最重的硬币划为一组,之后将剩下的分成两组,最后整合即可

代码:

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

int main(){
    int t;
    cin >> t;
    while(t--){

        int n;
        cin >> n;
        int a = 0,b = 0;
        a = pow(2,n);
        for(int i = 1;i < n/2;i++){
            a += pow(2,i);
        }
        for(int i = n/2;i < n;i++){

            b += pow(2,i);
        }

        int ans;
        ans = abs(a-b);
        cout << ans << endl;
    }
}

B - Phoenix and Beauty

题意:给出一个数组和k,要求完美数组,即连续k个数之和相同。

做法:需要扩充数列,但存在无法扩充的情况,即数组中数的种类大于k的话是无法构造的(无法保证以k为长度的子序列包含所有数,即无法保证和均相同),如果小于k,可以构造;因为题目没有规定构造的子序列长度,所以多长都行,可以直接把n*m作为长度,之后每个子序列把所有出现的数都安排一个上去,数量不够就找一个之前没有出现过的数补上(我懒,直接用的 n,严格意义上讲不对)。

代码:

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

int a[200],m[200];

int main(){
    int t;
    cin >> t;

    while(t--){
        int n,k;
        int x;
        memset(a,0,sizeof(a));
        memset(m,0,sizeof(m));
        int num = 0;
        cin >> n >> k;
        for(int i = 1;i <= n;i++){

            cin >> x;

            if(a[x] == 0){
                a[x] = 1;
                num++;
                m[num] = x;
            }
        }

            if(num > k){
                cout << -1 << endl;
            }else{
                cout << n*k << endl;

                for(int h = 1;h <=n;h++){
                    for(int i = 1;i <= num;i++){
                        cout << m[i] <<  ;
                    }

                    for(int i = 0;i < k-num;i++){

                        cout << n <<  ;
                    }
                }
                cout << endl;

            }


        }
    }

C - Road To Zero

题意:可以分别付a刀和b刀对输入的x和y做出两种操作,一种是给其中一个数加一或减一,还有一种是给两个同时加一或减一,求最少的钱将两个数都变成0

做法:两种方案,一种是全付a刀一个一个减,还有一种是先用b刀方案把最少的那个数减成0,再用a刀方案减剩下的数,两个方案对比找花钱最少的就行

代码:

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

int main(){
    int t;
    cin >> t;
    while(t--){
        LL x,y;
        cin >> x >> y;
        LL a,b;
        cin >> a >> b;

        LL sum1,sum2;
        sum1 = (x+y)*a;
        sum2 = min(x,y)*b + a*(max(x,y)-min(x,y));

        LL ans;
        ans = min(sum1,sum2);

        cout << ans << endl;
    }
}

D - Binary Period

题意:简单点讲就是给出一个序列,将其作为子序列求周期最短的序列

做法:如果序列只包含一个数,那就输出其本身就好,因为题目并未规定输出的成品序列要多长,多长都行;如果同时包含0和1,那他的最短周期就是01,输出出来就行

代码:

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

char s[3000];

int main(){
    int t;
    cin >> t;
    while(t--){
        scanf("%s",&s);

        int flag = 1;

        for(int i = 0;i < strlen(s)-1;i++){
            if(s[i] != s[i+1]){
                flag = 0;
                break;
            }
        }

        if(flag == 0){
            for(int i = 0;i < strlen(s);i++){
                cout << "01" ;

            }
            cout << endl;
        }else{
            cout << s << endl;
        }

    }
}

E - Nastya and Rice

题意:抛弃题目背景,问的就是给出a、b、c、d和n,求可否讲a-b到a+b这个区间乘n,使之与c-d到c+d产生交集

做法:直接算,求出所需两个范围之后,只需要比较断点值大小即可

代码:

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

int main(){
    int t;
    cin >> t;
    while(t--){
        int a,b,c,d,n,a1,b1,c1,d1;
        cin >> n >> a >> b >> c >> d ;
        a1 = (a-b)*n;
        b1 = (a+b)*n;
        c1 = c-d;
        d1 = c+d;

        if((a1 >= c1 && a1 <= d1)||(b1 >= c1 && b1 <= d1)||(a1 <= c1 && b1 >= d1))
            cout << "Yes" << endl;
        else
            cout << "No" << endl;
    }
}

F - Nastya and Door

题意:给出一串山峰值,之后给定一个范围,若其中一个值大于其两边的值(和极大值差不多),就算是巅峰,之后问在这串山峰值中,连续k个里面,巅峰数最多的区间所含的被巅峰分割的区域(就是巅峰值加一),以及这个区间里最靠左的山峰的坐标,如有相同答案优先输出最左边的

做法:先输入山峰值,之后挨个判断是不是巅峰,记录下巅峰的个数,之后按照k循环整个序列,找出巅峰最多的区间,之后就加一输出就行,坐标顺便也就出来了

代码:

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


int a[300000],b[300000] = {0};
int main(){
    int t;
    cin >> t;
    while(t--){

       // memset(a,0,sizeof(a));
       // memset(b,0,sizeof(b));
        int n,k;
        int sum = 0,m = 1;
        int num = 0;
        cin >> n >> k;
        for(int i = 1;i <= n;i++ ){
            cin >> a[i];
        }


        for(int i = 1;i <= n;i++){
            if(a[i] > a[i-1] && a[i] > a[i+1]){
                num++;
            }
                b[i] = num;

        }


        for(int i = 1;i <= n-k+1;i++){

            int cnt = b[i+k-2] - b[i];

            if(cnt > sum){
                m = i;
                sum = cnt;
            }
        }
        cout << sum+1 << " " << m << endl;


    }
}

 

2020.5.18 习题训练一

原文:https://www.cnblogs.com/CCCCrack/p/12926387.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!