Codeforces 1215

Posted blogofchc1234567890

tags:

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

A.

分类讨论。

Code

#include<bits/stdc++.h>
using namespace std;
const int maxn=100003;
int main(){
    int a1,a2,k1,k2,n;
    cin>>a1>>a2>>k1>>k2>>n;
    if(k1>k2)swap(a1,a2),swap(k1,k2);
    int ans1=n/k1;
    if(ans1>a1)ans1=a1+(n-a1*k1)/k2;
    int tmp=n/a2,ans2;
    if(tmp<k2-k1)ans2=0;
    else{
        int m=n-a2*(k2-k1);
        tmp=(m+a1+a2-1)/(a1+a2);
        if(tmp<k1)ans2=0;
        else if(tmp==k1)ans2=(m%(a1+a2)==0?a1+a2:m%(a1+a2));
        else ans2=a1+a2;
    }
    cout<<ans2<<' '<<ans1;
    return 0;
}

B.

考虑前缀和的正负性。

C.

(^{a;a}_{b;b} ightarrow ^{a;b}_{a;b})
(^{a;b}_{b;a} ightarrow ^{a;a}_{b;b} ightarrow ^{a;b}_{a;b})

执行完以上转换后,如果还没相等,那就不可能。

Code

#include<bits/stdc++.h>
using namespace std;
const int maxn=200003;
int n;
char s[maxn],t[maxn];
vector<int> u,v;
int main(){
    scanf("%d%s%s",&n,s+1,t+1);
    for(int i=1;i<=n;i++){
        if(s[i]=='a'&&t[i]=='b')u.push_back(i);
        if(s[i]=='b'&&t[i]=='a')v.push_back(i);
    }
    if(u.size()%2+v.size()%2==1){puts("-1");return 0;}
    int cnt=u.size()/2+v.size()/2+u.size()%2+v.size()%2;
    printf("%d
",cnt);
    for(int i=0;i+1<int(u.size());i+=2){
        printf("%d %d
",u[i],u[i+1]);
    }
    for(int i=0;i+1<int(v.size());i+=2){
        printf("%d %d
",v[i],v[i+1]);
    }
    if(u.size()%2+v.size()%2){
        printf("%d %d
%d %d
",u.back(),u.back(),u.back(),v.back());
    }
    return 0;
}

D.

被叉掉了

Code

#include<bits/stdc++.h>
using namespace std;
const int maxn=200003;
int n,cnt0,cnt1,sum0,sum1;
char s[maxn];
int main(){
    scanf("%d%s",&n,s+1);
    for(int i=1;i<=n/2;i++){
        if(s[i]=='?')cnt0++;
        else sum0+=s[i]-48;
    }
    for(int i=n/2+1;i<=n;i++){
        if(s[i]=='?')cnt1++;
        else sum1+=s[i]-48;
    }
    if(sum0<sum1)swap(cnt0,cnt1),swap(sum0,sum1);
    int game=(cnt0+cnt1)/2;
    for(int i=1;i<=game;i++){
        if(cnt0){
            sum0+=9;
            cnt0--;
        }
        else{
            cnt1--;
            if(sum1+9>sum0)sum1+=9,swap(sum0,sum1),swap(cnt0,cnt1); // important
        }
        if(cnt1){
            sum1+=min(9,sum0-sum1);
            cnt1--;
        }
        else{
            cnt0--;
        }
    }
    puts(sum0==sum1?"Bicarp":"Monocarp");
    return 0;
}

E.

看到20,4s,考虑状压。
先预处理出 (pre[i][j]) 表示位置1到i有多少个元素等于j,然后在用其处理出 (sum[i][j]) 表示序列中每个等于i的元素的pre[j]之和。
然后 (O(2^n*n^2)) 状压dp,对于已处理的集合S和不在S中的i,我们的目标是把所有等于i的元素移到未处理元素的左边,S中元素的右边。这样它的贡献就是 (sum sum[i][j](j≠i,j?S))
有点类似统计逆序对。

Code

#include<bits/stdc++.h>
using namespace std;
typedef long long D;
const int maxn=400003,maxm=20,maxb=1<<maxm;
const D INF=0x3f3f3f3f3f3f3f3fll;
int n,a[maxn],pre[maxn][maxm];
D dp[maxb],sum[maxm][maxm];
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",a+i),a[i]--;
    for(int i=1;i<=n;i++){
        for(int j=0;j<maxm;j++)pre[i][j]=pre[i-1][j];
        pre[i][a[i]]++;
    }
    for(int i=1;i<=n;i++){
        for(int j=0;j<maxm;j++){
            sum[a[i]][j]+=pre[i][j];
        }
    }
    memset(dp,0x3f,sizeof(dp));
    dp[0]=0;
    for(int S=0;S<maxb;S++){
        for(int i=0;i<maxm;i++){
            if(!((S>>i)&1)){
                D res=0;
                for(int j=0;j<maxm;j++){
                    if(i!=j&&!((S>>j)&1)){
                        res+=sum[i][j];
                    }
                }
                dp[S|(1<<i)]=min(dp[S|(1<<i)],dp[S]+res);
            }
        }
    }
    printf("%lld
",dp[maxb-1]);
    return 0;
}

以上是关于Codeforces 1215的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces 1215E. Marbles

codeforces 1215 E Marbles-----状压DP

Codeforces Round #585 (Div. 2) CF1215A~C

[Codeforces Round #522 (Div. 2, based on Technocup 2019 Elimination Round 3)][C. Playing Piano](代码片段

c_cpp Codeforces片段

如何设置 vscode 的代码片段,以便在自动完成后自动触发 vscode 的智能感知?