Codeforces Round #638 (Div. 2).abcd

https://codeforces.ml/contest/1348

晚上的刷题计划正式启动了 所以每天早上记录一下

昨晚挑了这一场 感觉好难 看了下队友们的当时的情况
好像都不怎么乐观 大家都在掉分(还好当时没打 hhhh)
就出了ab两题昨晚
cd终于补完了

A. Phoenix and Balance

题目思路

直接两两配对相减 就好了

ac代码

 #include <stdio.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <utility>
#define pi 3.1415926535898
#define ll long long
#define lson rt<<1
#define rson rt<<1|1
#define eps 1e-6
#define ms(a,b) memset(a,b,sizeof(a))
#define legal(a,b) a&b
#define print1 printf("111\n")
using namespace std;
const int maxn = 1e5+10;
const int inf = 0x1f1f1f1f;
const int mod = 2333;
 
int a[maxn],b[maxn];
map<int,int>mp;
 
int main()
{
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        int tem=1;
        ll ans=0;
        for(int i=1;i<=n/2;i++)
        {
            tem*=2;
            ans+=tem;
        }
        printf("%lld\n",ans);
    }
}

B. Phoenix and Beauty

题目思路

题目给出n个数 要求输出是每个长度为k的区间和要相同
一直想着直接构造数组 但是要么mle 要么re 很头疼
看了下题解 说用set记录出现了多少种不同的数
构造一个长度为k的循环节
然后输出n边就好了
(菜鸡不晓得用set 写了快一个小时才搞好)

ac代码:

 #include <stdio.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <utility>
#define pi 3.1415926535898
#define ll long long
#define lson rt<<1
#define rson rt<<1|1
#define eps 1e-6
#define ms(a,b) memset(a,b,sizeof(a))
#define legal(a,b) a&b
#define print1 printf("111\n")
using namespace std;
const int maxn = 1e7+10;
const int inf = 0x1f1f1f1f;
const int mod = 2333;
 
int a[maxn];
set<int>s;
 
int main()
{
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    int t;
    scanf("%d",&t);
    while(t--)
    {
        s.clear();
        int n,k,cnt=0;
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            s.insert(a[i]);
        }
        if(s.size()>k)//如果出现的不同数值多余k那么一定无法满足题目条件
            printf("-1\n");
        else
        {
            printf("%d\n",n*k);
            for(int i=0;i<n;i++)
            {
                for(set<int>::iterator it=s.begin();it!=s.end();it++)
                {
                    printf("%d ",*it);
                }
                for(int j=s.size();j<k;j++)
                    printf("1 ");
            }
            printf("\n");
        }
    }
}

来补c题了

C - Phoenix and Distribution

题目思路

看完题目啥思路都没有 甚至题意都不是很懂
看了好久题解才搞懂这道题到底咋做

题目给出字符串长度n和要分成的区间个数k
要求输出区间字典序的最大值最小时的区间包含的字符串

就挺头疼的看完题目 很考分析的一道题
首先根据题意 结果与原串字符顺序无关 故先对原串排序
然后按照顺序将前k个字符装入k个桶
之后判断最小的那个字符是否够排满k个桶

不能的话直接输出第k个字符就好了 k后面的数直接装到前面
这是第k个桶的字典序最大 并且是所有最大值中最小的

能的话再进行分析
后面的所有字符是否相同
相同就将后面的字符均摊在k个桶中
如果不同就把所有的值全部放到第一个桶中
这里我也讲不太清为什么 原谅我这个菜鸡 建议结合字典序定义进行理解

这题的分析还是很巧妙地 很适合我这种菜鸡学习

ac代码

 #include <stdio.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <utility>
#define pi 3.1415926535898
#define ll long long
#define lson rt<<1
#define rson rt<<1|1
#define eps 1e-6
#define ms(a,b) memset(a,b,sizeof(a))
#define legal(a,b) a&b
#define print1 printf("111\n")
using namespace std;
const int maxn = 2e5+10;
const int inf = 0x1f1f1f1f;
const int mod = 2333;

string a,s;

int main()
{
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,k;
        scanf("%d%d",&n,&k);
        cin>>a;
        sort(a.begin(),a.end());
        if(a[k-1]!=a[0])
            cout<<a[k-1];
        else
        {
            int flag=0;
            for(int i=k;i<a.length()-1;i++)
            {
                if(a[i]!=a[i+1])
                {
                    flag=1;
                    break;
                }
            }
            if(flag==1)
            {
                for(int i=k-1;i<a.length();i++)
                    cout<<a[i];
            }else
            {
                for(int i=0;i<a.length();i+=k)
                    cout<<a[i];
            }
        }
        printf("\n");
    }
}

d待补

D. Phoenix and Science

题目思路
因为分裂只是影响每天晚上加的值 所以题目下面的那些花里胡哨的小数都没啥用
首先将n分解 从1开始减 每次将减的数乘二并加入数组 最后剩下的数也加入数组 并排序 这就是每晚要增加的数的最优解的一种
举个例子
20 分解成1 2 4 8 5 排序后为1 2 4 5 8
具体操作见代码

ac代码

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <utility>
#define pi 3.1415926535898
#define ll long long
#define lson rt<<1
#define rson rt<<1|1
#define eps 1e-6
#define ms(a,b) memset(a,b,sizeof(a))
#define legal(a,b) a&b
#define print1 printf("111\n")
using namespace std;
const int maxn = 2e5+10;
const int inf = 0x1f1f1f1f;
const ll llinf =1e17+10;
const int mod = 2333;

int a[maxn],sum[maxn];

int main()
{
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        int cnt=0;
        int tem=n;
        int c=1;
        while(tem>=c)
        {
            tem-=c;
            a[cnt++]=c;
            c*=2;
        }
        if(tem>0)
            a[cnt++]=tem;//这里要注意特判一下0 防止0来影响数组
        sort(a,a+cnt);
        printf("%d\n",cnt-1);
        for(int i=1;i<cnt;i++)
        {
            printf("%d ",a[i]-a[i-1]);
        }
        printf("\n");
    }
}

猜你喜欢

转载自blog.csdn.net/daydreamer23333/article/details/107332151