Codeforces Round 963 (Div. 2) A~C

封面原图 画师やんよ
掉大分的一场 连夜补题 真的不会写啊真的红温了

A - Question Marks

题意

选择题中答案为ABCD的题目各有n道,小明的答案给你,其中?表示这道题空着没写,问他的最高得分

思路

空着的题目肯定没分 超出选项最大个数的肯定也是错的

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

void solve()
{
    int n;
    scanf("%d",&n);
    string s;
    cin>>s;
    int A=0,B=0,C=0,D=0;
    int cnt=0;
    for(char c: s)
    {
        if(c=='A') A++;
        if(c=='B') B++;
        if(c=='C') C++;
        if(c=='D') D++;
        if(c=='?') cnt++;
    }
    int ans=s.length();
    ans-=A-n>0?A-n:0;
    ans-=B-n>0?B-n:0;
    ans-=C-n>0?C-n:0;
    ans-=D-n>0?D-n:0;
    ans-=cnt;
    printf("%d\n",ans);
}

int main()
{
    int T=1;
    scanf("%d",&T);
    while(T--)
    {
        solve();
    }
    return 0;
}

B - Parity and Sum

题意

给一个数列,每次可以任选两个奇偶性不同的数把其中较小的数变成两个数的和,问至少多少次可以使整个数列的奇偶性相同

思路

每次修改肯定是改出一个奇数,所以除了一开始全是偶数的特判之外我的目标一定是变成奇数,而偶数变成奇数只需要和一个比他的的奇数做题目给出的操作即可,我肯定是尽量要有更多更大的奇数,所以每个偶数都和最大的奇数做操作,如果一直到最后还是有偶数比最大的奇数还大那就操作两次,第一次把奇数变成一个更大的奇数第二次把偶数用这个更大的奇数变成新的奇数即可

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

void solve()
{
    ll n;
    scanf("%lld",&n);
    priority_queue<ll> p;
    priority_queue<ll,vector<ll>,greater<ll>> q;
    ll m=0;
    for(ll i=0;i<n;i++)
    {
        ll x;
        scanf("%lld",&x);
        if(x&1)
        {
            p.push(x);
        }
        else
        {
            m=max(m,x);
            q.push(x);
        }
    }
    if(p.size()==n or q.size()==n)
    {
        printf("0\n");
        return;
    }
    if(m<p.top())
    {
        printf("%d\n",q.size());
        return;
    }
    else
    {
        m=q.size()+1;
    }
    ll ans=0;
    while(q.size())
    {
        ll a=p.top();
        ll b=q.top();
        if(b<a)
        {
            q.pop();
            p.push(a+b);
        }
        else
        {
            p.pop();
            p.push(a+b);
        }
        ans++;
    }
    ans=min(ans,m);
    printf("%lld\n",ans);
}

int main()
{
    int T=1;
    scanf("%d",&T);
    while(T--)
    {
        solve();
    }
    return 0;
}

C - Light Switches

题意

有n个开关,一开始都是关的,第一次打开是在 a i a_i ai时刻,之后每 k k k分钟按一次,问最早什么时候所有开关都是开的状态

思路

首先我们要找的时间一定比最后开的开关还靠后,我们的第一步是先要统一我们要找的区间(检查他是否能够让所有开关都打开)的起点,但是实际上前面部分开关开的时间覆盖的区间的起点可能在这一段之前,所以我们要先往右边移动两格,第一次是移动到最右边的第一个关灯的位置,然后再移到下一个开灯的位置,注意在这里判断每个灯之前开关灯次数的奇偶性判断到底要不要在这里多开关一次统一灯的状态,具体看一下这个图
在这里插入图片描述
然后我们再判断我们找到的这个区间有没有机会满足所有开关都打开就可以了

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

void solve()
{
    ll n,k;
    scanf("%lld%lld",&n,&k);
    vector<ll> a(n);
    for(ll i=0;i<n;i++)
    {
        scanf("%lld",&a[i]);
    }
    sort(a.begin(),a.end());
    ll t=a.back();//最大值
    for(int i=0;i<n;i++)
    {
        ll cnt=1ll+(a.back()-a[i])/k;
        if(cnt%2ll==0ll)
            t=max(t,a[i]+cnt*k);
    }
    ll _t=t;
    for(int i=0;i<n;i++)
    {
        ll cnt=1ll+(t-a[i])/k;
        if(cnt%2ll==0ll)
            _t=max(_t,a[i]+cnt*k);
    }
    for(int i=0;i<n;i++)
    {
        ll cnt=1ll+(_t-a[i])/k;
        if(cnt%2ll==0ll)
        {
            printf("-1\n");
            return ;
        }
    }
    printf("%lld\n",_t);
}

int main()
{
    int T=1;
    scanf("%d",&T);
    while(T--)
    {
        solve();
    }
    return 0;
}
  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值