codeforces 357

D. Xenia and Hamming

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1000005;
char a[maxn],b[maxn];
ll cnt[maxn][30]={0};
ll gcd(ll x, ll y) {
    return y==0?x:gcd(y,x%y);
}
int main() {
    ll n,m,g,alen,blen,len,ans=0;
    scanf("%I64d%I64d",&n,&m);
    scanf("%s%s",a,b);
    alen=strlen(a);
    blen=strlen(b);
    g=gcd(alen,blen);
    len=alen*blen/g;
    for(int i=0;i<alen;++i) 
        ++cnt[i%g][a[i]-'a'];
    
    for(int i=0;i<blen;++i) 
        ans+=cnt[i%g][b[i]-'a'];
    
    ans=n*alen-n*alen/len*ans;
    printf("%I64d\n",ans);
    return 0;
}

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

E. Compartments

题意:有n个车厢,每个车厢有4个人,其中ai个学生,交换最少的人使得每个车厢的学生数为0或3或4,无法达成输出-1。

    思路:贪心。统计车厢内学生为1,2,3,4的数目cnt[1],cnt[2],cnt[3],cnt[4]。

   目标为最少的步数,过程中应先配出cnt[3],配不出3时考虑4。

1.首先考虑cnt[1]不为0时,尽可能让cnt[1]与cnt[2]配对,这样可以同时减少cnt[1]与cnt[2]的数目使二者符合要求,明显最优,即1 2 -> 3。

   然后考虑让三个1抱团 1 1 1 -> 3 ;剩下一个1时考虑 1 3 -> 4;剩下两个1时先考虑1 1 3 3 -> 4 4 ,再考虑1 1 -> 2。

   这些过程后若cnt[1]!=0,则无解。

2.考虑cnt[2]不为0时,2 2 2 -> 3 3;剩下一个2时先考虑 2 4 -> 3 3,再考虑 2 3 3 ->  4 4;剩下两个2时考虑 2 2 -> 4。

#include<bits/stdc++.h>
using namespace std;
int cnt[10]={0};
int main() {
    int n,x,ans=0,t;
    scanf("%d",&n);
    for(int i=0;i<n;++i) {
        scanf("%d",&x);
        ++cnt[x];
    }
    if(!cnt[1]&&!cnt[2]) {
        puts("0");
        return 0;
    }
    if(cnt[1]) {
        if(cnt[2]) { // 1 2 -> 3
            t=min(cnt[1],cnt[2]);
            ans+=t;
            cnt[1]-=t;
            cnt[2]-=t;
            cnt[3]+=t;
        }
        if(cnt[1]) {
       // 1 1 1 -> 3
            ans+=cnt[1]/3*2;
            cnt[3]+=cnt[1]/3;
            cnt[1]%=3;


            if(cnt[1]==2) { 
                if(cnt[3]>=2) ans+=2,cnt[3]-=2,cnt[4]+=2; // 1 1 3 3 -> 4 4
                else ++ans,++cnt[2]; // 1 1 -> 2
            }
            else if(cnt[1]==1) {
                if(cnt[3]) ++ans,--cnt[3],++cnt[4]; // 1 3 -> 4
                else if(cnt[1]&&cnt[4]<2) {
                    puts("-1");
                    return 0;
                }
                else cnt[4]-=2,ans+=2,cnt[3]+=3; // 1 4 4 -> 3 3 3
            }
            cnt[1]=0;
        }
    }
    if(cnt[2]) {
     // 2 2 2 -> 3 3
        ans+=cnt[2]/3*2;
        cnt[3]+=cnt[2]/3*2;
        cnt[2]%=3;


        if(cnt[2]==2) ans+=2,cnt[2]=0,++cnt[4]; // 2 2 -> 4
        else if(cnt[2]==1) {
            if(cnt[4]) ++ans,cnt[2]=0,--cnt[4],cnt[3]+=2; // 2 4 -> 3 3
            else if(cnt[3]>=2) ans+=2,cnt[2]=0,cnt[3]-=2,cnt[4]+=2; // 2 3 3 -> 4 4 
            else {
                puts("-1");
                return 0;
            }
        }
    }
    if(!cnt[1]&&!cnt[2]) printf("%d\n",ans);
    else puts("-1");
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值