首页 > 其他 > 详细

2020-05-18 习题训练一

时间:2020-05-20 09:40:17      阅读:36      评论:0      收藏:0      [点我收藏+]

题目Phoenix and Balance

题目链接:https://vjudge.net/problem/CodeForces-1348A

题目大意:

题目给出 t 组数据,对于每组数组给出一个n(n为偶数),将21   22  ........  2n  n 个数分成等份的两部分,求这两部分差的绝对值最小是多少。

思路:

将 2和(n/2)个较小的分在一起,剩下的分在一起,便可保证结果最小,然后通过列举几个情况,便可推出规律。

解题代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>
#include <map>
using namespace std;
const long long N = 1e10 + 7;
const int maxn = 2e5 + 5;
const long long INF = 8e18;
typedef long long ll;
#define for0(i,n) for(int i = 0;i < n;i++)
#define for1(i,n) for(int i = 1;i <= n;i++)

int main()
{
    int t;
    cin >> t;
    while(t--){
        ll num = 0;
        int n;
        cin >> n;
        for(int i = 0;i < n;i += 2){
            num = 2*num+2;
        }
        cout << num << endl;

    }
    return 0;

}

题目:Phoenix and Beauty

题目链接:https://vjudge.net/problem/CodeForces-1348B

题目大意:

题目给出 t 组数据,对于每组数组给出 n , m,然后再给出 n 个数的数列。让你通过在数列中插入若干数,使得数列每m个连续数的和都相等,若不能构造则输出-1。

思路:

首先想到将n个数对应每个位置变成一个含数列中所有数的一个数列,这样便可符合题目条件。所有当给出的数列中不相等的数目大于m时,遍不可构造,另外情况下可构造。首先遍历数列统计出不相同的数的个数并存入另外的数组总,然后根据与m的个数控制输出形式,如果不相同的数的个数小于m再找一个数组外的数凑出。

解题代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>
#include <map>
using namespace std;
const long long N = 1e10 + 7;
const int maxn = 2e5 + 5;
const long long INF = 8e18;
typedef long long ll;
#define for0(i,n) for(int i = 0;i < n;i++)
#define for1(i,n) for(int i = 1;i <= n;i++)
int a[110],sign[110];
int main()
{
    int t;
    cin >> t;
    while(t--){
        int n,m,num,j = 0,temp;

        cin >> n >> m;
        for0(i,n){
            cin >> num;
            if(!sign[num]){
                sign[num]++;
                a[j++] = num;
            }

        }
        for1(i,100){
            if(!sign[i]){
                temp = i;   //寻找一个没有出现的数,用于后面可能的填充。
                break;
            }

        }
        if(j > m)
            cout << -1 << endl;
        else{
            cout << n*m << endl;
            for(int y = 0;y < n;y++){
                for0(i,j){
                    cout << a[i] << " ";
                }
                for0(i,m-j){
                    cout << temp << " ";
                }

            }
            cout << endl;

        }
        memset(a, 0, sizeof(a));
        memset(sign, 0, sizeof(sign));
    }

}

 

题目Road To Zero

题目链接:https://vjudge.net/problem/CodeForces-1342A

 

思路:

每组数据给出的 x , y(假设x>y),则比较 x~y用操作1,然后用操作2,和 只用操作1的费用就可。

解题代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>
using namespace std;
const long long N = 1e10 + 7;
const int maxn = 2e5 + 5;
const long long INF = 8e18;
typedef long long ll;
#define for0(i,n) for(int i = 0;i < n;i++)
#define for1(i,n) for(int i = 1;i <= n;i++)
 
int main()
{
    int t;
    cin >> t;
    while(t--)
    {
        ll a,b,x,y;
        cin >> x >> y >> a >> b;
        if(x < y)
            swap(x,y);
        ll num1 = a * (x+y);
        ll num2 = a * (x-y) + b * y;
        cout << min(num1,num2) << endl;
    }
    return 0;
}

题目:Binary Period

题目链接:https://vjudge.net/problem/CodeForces-1342B

题目大意:

题目给出 t 组数据,对于每组数组给出一个01串,让你找出一个新串长度小于大于之前串的二倍,并且给出的串是新串的子串,还要使新串的循环节最少。

思路:

由此可以想到,当给出的串是全1串或全0串时,直接输出原串便可,反之,则以 “10”或“01”作为循环,输出 l 遍(原串长度为 l )。

解题代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>
using namespace std;
const long long N = 1e10 + 7;
const int maxn = 2e5 + 5;
const long long INF = 8e18;
typedef long long ll;
#define for0(i,n) for(int i = 0;i < n;i++)
#define for1(i,n) for(int i = 1;i <= n;i++)

int main()
{
    int t;
    cin >> t;
    while(t--)
    {
        string s;
        int num1 = 0,num2 = 0;
        cin >> s;
        for0(i,s.size()){
            if(s[i] == 0)
                num1 = 1;
            if(s[i] == 1)
                num2 = 1;
            if(num1&&num2)
                break;
        }
        if(num1&&num2){
            for0(i,s.size())
                cout << "10";
            cout << endl;

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

题目:Nastya and Rice

题目链接:https://vjudge.net/problem/CodeForces-1341A

题目大意:

对于每组数据给出n,a,b,c,d,本题假设判断 [ n*(a-b)  ,  n*(a+b) ]  与 [ c-d , c+d ] 是否有交集。

 

解题代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>
using namespace std;
const long long N = 1e10 + 7;
const int maxn = 2e5 + 5;
const long long INF = 8e18;
typedef long long ll;
#define for0(i,n) for(int i = 0;i < n;i++)
#define for1(i,n) for(int i = 1;i <= n;i++)

int main()
{
    int t;
    cin >> t;
    while(t--){
        int a,b,c,d,n;
        cin >> n >> a >> b >> c >> d;
        if( n*(a-b) <= (c+d) && n*(a+b) >= (c-d) )
            cout << "YES" << endl;
        else
            cout << "NO" << endl;

    }
    return 0;
}

题目:Nastya and Door

题目链接:https://vjudge.net/problem/CodeForces-1341B

题目大意:

题目给出 t 组数据,对于每组数组给出 n,k 接下来给出 n个数代表山的高度。需要寻找 连续的 k座山中存在最多的顶峰区间(顶峰:ai  > ai+1 且ai  > ai-1),要求输出将该区间单独分割需要多少个门,以及该区间的左位置(若有多个答案,输出最小的那个)。

思路:

先对每一个山峰遍历,标记一下它是不是顶峰,然后求一下前缀和得到区间顶峰数(然而划定区间内不一定都是顶峰,需要再判断一下边界,也可收缩一下区间)(详情看代码注释)。

解题代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>
using namespace std;
const long long N = 1e10 + 7;
const int maxn = 2e5 + 5;
const long long INF = 8e18;
typedef long long ll;
#define for0(i,n) for(int i = 0;i < n;i++)
#define for1(i,n) for(int i = 1;i <= n;i++)
int sign[maxn],a[maxn];
int main()
{
    int t;
    cin >> t;
    while(t--){
        int n,k;
        int point = 1,maxnum = 0;
        cin >> n >> k;
        for1(i,n)  cin >> a[i];
        for(int i = 2;i < n;i++){
            if(a[i] > a[i-1] && a[i] > a[i+1])
                sign[i]++;
        }

        for1(i,n)  sign[i] += sign[i-1];
        for(int i = 1;i <= n-k+1;i++){
            int temp = sign[i+k-2] - sign[i];
       //此处其实求解是 [i , i+k-1]区间的顶峰数,然而这样求解可能会将边界的两个山峰错认为是顶峰,所以这里[i+1 , i+k-2]区间的峰数才是正确答案
if(temp > maxnum){ maxnum = temp; point = i; } } cout << maxnum+1 << " " << point << endl; memset(sign,0,sizeof(sign)); } return 0; }

 

2020-05-18 习题训练一

原文:https://www.cnblogs.com/emhhbw/p/12918994.html

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