Codeforces Round 963 (Div. 2) 8.4

8.4 Div 2

Dashboard - Codeforces Round 963 (Div. 2) - Codeforces

A. Question Marks

有4n个问题,答案分别为n个ABCD,给一个字符串,问最大答对几道。

水题,直接代码

代码

void solve()
{
    int n,a[10]={0};
    string s;
    cin>>n>>s;
    fir(i,0,s.size()-1)
    {
        if(s[i]=='A')
        a[1]++;
        if(s[i]=='B')
        a[2]++;
        if(s[i]=='C')
        a[3]++;
        if(s[i]=='D')
        a[4]++;
    }
    int ans=0;
    fir(i,1,4)
    ans+=min(n,a[i]);
    cout<<ans<<'\n';
    
}

B. Parity and Sum

给定一个由 n个正整数组成的数组

在一次操作中,你可以选取任意一对索引 i,j,a[i ]和a[ j] 具有不同的奇偶性,然后用它们的和替换较小的那个。

求使数组中所有元素具有相同奇偶性所需的最少操作数。

思路

奇数+偶数=奇数

全为奇数 0

全为偶数 0

奇偶混合 全变为奇数

如果最大的数不是偶数,那么有c个奇数,就操作c次

否则

偶数和最大奇数组合,生成的奇数再和其他偶数组合。

不断迭代,得到max奇数

再次比较max奇数和max偶数,

前者大 进行C次

后者大 进行C+1次

因为奇偶结合,先将奇数变大,再次结合替换偶数

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define fir(i,a,b) for(int i=a;i<=b;i++)
#define PII pair<int,int> 
#define fi first
#define se second
#define tup tuple<int,int,int>
int a[200050];
void solve()
{
    int n,j=0,o=0,mx=0,mj=0;
    int ou[200050];
    cin>>n;
    fir(i,1,n)
    {
        cin>>a[i];
        if(a[i]>mx)
        mx=a[i];
        if(a[i]&1) 
        {
            j++;
            mj=max(a[i],mj);
        } 
        else    ou[o++]=a[i];
    }
    sort(ou,ou+o);
    if(j==n||o==n)
    cout<<'0'<<'\n';
    else if(mx%2==0)//最大的是偶数
    {
        for(int i=0;i<o;i++)
        {
            if(ou[i]<mj)
            mj+=ou[i];
        }
       if(mj>mx) //再次比较
        cout<<o<<'\n';
        else
        cout<<o+1<<'\n';
    }
    else
    cout<<o<<'\n';
    
}
signed main()
{
    IOS
    int t;
    cin>>t;
    while(t--)
    solve();
    return 0;
}

C. Light Switches

n个灯,每k次变化一次开关状态。每个灯从a[i],开始变化。最快什么时候,全亮,不存在-1。

思路

可以通过对2*k,取模,进行判断。

如这个样例

4 4
2 3 4 5

2在2,10,18,26,也就是对2k 取模=2 时,开灯。

依此,3在 mod%2k=3,开灯

4 在mod%2k=4,开灯。 5在 mod%2k=5 ,开灯。

余数分别为 2 ,3,4,5

最大差值为3<k,此时可以全亮。

从5开始判断,5%mod2k=5,当对2k取模为5(也就是最大余数时),可以全亮。

还有一个重要情况

看这个样例

6 5
40 80 99 60 90 50

余数分别为0,9,按照刚才的思路,该输出 -1。并非如此。

2k=10。0 ,9看似差了9,实际上也是1,当t=100时,取模=0,也可以亮。

所以余数可以这样连2,1,0,9,8,这样如果距离<k,也是可以的。取模为0左边最大的数时,满足条件。

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define fir(i,a,b) for(int i=a;i<=b;i++)
int a[200050],b[200050];
void solve()
{
    int n,k,mx=0,f=0;
    cin>>n>>k;
    int m1=-1,m2=2*k;
    fir(i,1,n)
    {
        cin>>a[i];
        b[i]=a[i]%(k*2);
        mx=max(mx,a[i]);
        if(b[i]==k)
        f=1;
        else if(b[i]<k)
            m1=max(b[i],m1);
        else
        m2=min(m2,b[i]-2*k);
    }
     sort(b,b+n+1);
     if(f==0)//有可能首尾连
     {
         if(m1-m2>=k)
         f=1;
     }
     if(b[n]-b[1]>=k&&f==1)
     {
         cout<<"-1"<<'\n';
     }
     else
     {
         int i=mx;
         while(1)
         {
             if((i%(2*k)>=b[n]&&i%(2*k)-k<b[1])||i%(2*k)==m1)
             break;
             else
             i++;
         }
         cout<<i<<'\n';
     }  
}
signed main()
{
    IOS
    int t;
    cin>>t;
    while(t--)
    solve();
    return 0;
}
  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值