Codeforces Round #642 (Div. 3)-A,B,C,D,E

时间:2020-05-16
本文章向大家介绍Codeforces Round #642 (Div. 3)-A,B,C,D,E,主要包括Codeforces Round #642 (Div. 3)-A,B,C,D,E使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

codeforces-1353-A. Most Unstable Array

题意:给你两个数n,m,让你构造一个长度为n个数列a,使得数列中每个数的和为m,且让 最大,并输出

如果n>2 最大就是ans=2*m 构造是序列是 0,m,0,0,……,但是如果n==2,就是0,m,ans=m,分类讨论

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(a) ((a)&-(a))
#define clean(a,b) memset(a,b,sizeof(a))
const int mod = 1e9 + 7;
const int inf=0x3f3f3f3f;
const int maxn = 2e5+9;
 
inline int read(){char c=getchar();int tot=1;while ((c<'0'|| c>'9')&&c!='-') c=getchar();if (c=='-'){tot=-1;c=getchar();}
int sum=0;while (c>='0'&&c<='9'){sum=sum*10+c-'0';c=getchar();}return sum*tot;}
 
int _;
//==================================================================

//==================================================================
int main()
{
    for(scanf("%d",&_);_;_--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        if(n==1) printf("0\n");
        else if(n==2) printf("%d\n",m);
        else printf("%d\n",m*2);
    }
    return 0;
}

codeforces-1353-B. Two Arrays And Swaps

题意:给你两个数组a,b,均由正数组成,再给你一个整数k,你有k次机会把a,b数组里的某一对数交换一下,问交换之后a数组的和的最大值

因为有k次机会交换,那就是有k次机会用b数组里大的数替代a里比较小的,分别对两数组从小到大排序,前k个从b的后面往前面取,如果a[i]>=b[n-i+1] break;后面加上a数组剩下的 就可以了
代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(a) ((a)&-(a))
#define clean(a,b) memset(a,b,sizeof(a))
const int mod = 1e9 + 7;
const int inf=0x3f3f3f3f;
const int maxn = 2e5+9;
 
inline int read(){char c=getchar();int tot=1;while ((c<'0'|| c>'9')&&c!='-') c=getchar();if (c=='-'){tot=-1;c=getchar();}
int sum=0;while (c>='0'&&c<='9'){sum=sum*10+c-'0';c=getchar();}return sum*tot;}
 
int _;
//==================================================================
int a[100],b[100];
//==================================================================
int main()
{
    for(scanf("%d",&_);_;_--)
    {
        int n,k;
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=1;i<=n;i++) scanf("%d",&b[i]);
        sort(a+1,a+1+n);
        sort(b+1,b+1+n);
        int ans=0,r=0;
        for(int i=1;i<=k;i++)
        {
            if(a[i]>=b[n-i+1]) break;
            r=i;
            if(a[i]<b[n-i+1]) ans+=b[n-i+1];
        }
        for(int j=r+1;j<=n;j++) ans+=a[j];
        printf("%d\n",ans);
     }
    return 0;
}

codeforces-1353-C. Board Moves

题意:上图把

就是这样,这是n=7的情况,我们可以把这个图分成8部分,每部分都是for(ll i=1;i<=n/2;i++) ans+= i * i *8;
注意循环里要开long long

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(a) ((a)&-(a))
#define clean(a,b) memset(a,b,sizeof(a))
const int mod = 1e9 + 7;
const int inf=0x3f3f3f3f;
const int maxn = 2e5+9;
 
inline int read(){char c=getchar();int tot=1;while ((c<'0'|| c>'9')&&c!='-') c=getchar();if (c=='-'){tot=-1;c=getchar();}
int sum=0;while (c>='0'&&c<='9'){sum=sum*10+c-'0';c=getchar();}return sum*tot;}
 
int _;
//==================================================================
int a[100],b[100];
//==================================================================
int main()
{
    for(scanf("%d",&_);_;_--)
    {
        int n;
        scanf("%d",&n);
        ll ans=0;
        for(ll i=1;i<=n/2;i++)
        {
            ans+=i*i*8;
        }
        printf("%lld\n",ans);
     }
    return 0;
}

codeforces-1353-D. Constructing the Array

题意:一个长度为 n 的数组,初始值全部为 0
每次选择其中最长的一段全0连续子数组,如果多个并列最长,取最左边的那个,并标记其左右区间 L R
如果这个子数组包含的元素个数为奇数(R-L+1为奇数),则将这一段区间最中间那个位置标记上数字
如果这个子数组包含的元素个数为偶数,则将这一段区间内中间靠左的那个位置标记上数字
数字依次标记 1~n,最后输出这个数组

每次选择其中最长的一段全0连续子数组,那么我们可以搞一个优先队列,每个元素就是一整段连续的0,按照全0连续子数组的长度来排序,每次从队列取出来的时候,给中间的赋值,然后再把他掰断扔进队列,直到长度都为1

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(a) ((a)&-(a))
#define clean(a,b) memset(a,b,sizeof(a))
const int mod = 1e9 + 7;
const int inf=0x3f3f3f3f;
const int maxn = 2e5+9;
 
inline int read(){char c=getchar();int tot=1;while ((c<'0'|| c>'9')&&c!='-') c=getchar();if (c=='-'){tot=-1;c=getchar();}
int sum=0;while (c>='0'&&c<='9'){sum=sum*10+c-'0';c=getchar();}return sum*tot;}
 
int _;
//==================================================================

//==================================================================
int ans[maxn];
struct node
{
    int l,r,di;
    bool operator<(const node&a) const
    {
        return di==a.di&&l>a.l||di<a.di;
    }
};
priority_queue<node>qu;
int main()
{
    for(scanf("%d",&_);_;_--)
    {
        int n;
        scanf("%d",&n);
        if(n==1)
        {
            printf("1\n");
            continue;
        }
        if(n==2)
        {
            printf("1 2\n");
            continue;
        }
        int cnt=1;
        node now;
        now.l=1;
        now.r=n;
        now.di=(now.r-now.l+1);
        qu.push(now);
        while(!qu.empty())
        {
            now=qu.top();
            qu.pop();
            node a,b;
            int mid=(now.l+now.r)/2;
            ans[mid]=cnt;
            cnt++;
            if(now.l!=mid)
            {
                a.l=now.l;
                a.r=mid-1;
                a.di=a.r-a.l+1;
                qu.push(a);
            }
            if(now.r!=mid)
            {
                b.l=mid+1;
                b.r=now.r;
                b.di=b.r-b.l+1;
                qu.push(b);
            }
        }
        for(int i=1; i<n; i++) printf("%d ",ans[i]);
        printf("%d\n",ans[n]);
    }
    return 0;
}

codeforces-1353-E. K-periodic Garland

题意:有一个01串,0代表灯关着1代表开着,给你一个k,开 或者关灯 让这个01串每对相邻的1差k-1
感觉是一个dp呢
枚举1-n dp[i]=min(他前面都是0从他开始是1需要开关灯的次数,dp[i-k]+(i-k到i这段需要关灯的次数)+(如果本来是关的那么打开,开的就不用加))
ans=min(ans,dp[i]+(以他做结尾后面都是0需要改的次数))

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(a) ((a)&-(a))
#define clean(a,b) memset(a,b,sizeof(a))
const int mod = 1e9 + 7;
const int inf=0x3f3f3f3f;
const int maxn = 1e6+9;
 
inline int read(){char c=getchar();int tot=1;while ((c<'0'|| c>'9')&&c!='-') c=getchar();if (c=='-'){tot=-1;c=getchar();}
int sum=0;while (c>='0'&&c<='9'){sum=sum*10+c-'0';c=getchar();}return sum*tot;}
 
int _;
//==================================================================
int a[maxn],hsum[maxn],dp[maxn];
//==================================================================
int main()
{
    for(scanf("%d",&_);_;_--)
    {
        int n,k;
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++) scanf("%1d",&a[i]);
        for(int i=1;i<=n;i++) 
        {
            if(a[i]==1) hsum[i]=hsum[i-1]+1;
            else hsum[i]=hsum[i-1];
        }
        int ans=inf;
        for(int i=1;i<=n;i++)
        {
            if(i>k) dp[i]=min(hsum[i-1],dp[i-k]+hsum[i-1]-hsum[i-k])+(a[i]==0);
            else dp[i]=hsum[i-1]+(a[i]==0);
            ans=min(ans,dp[i]+hsum[n]-hsum[i]);
        }
        ans=min(ans,hsum[n]);
        printf("%d\n",ans);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/YangKun-/p/12900147.html