Codeforces Round #740 (Div. 2, based on VK Cup 2021 - Final (Engine))B C

B
题目大意:
有两个人打羽毛球轮流发球
现在知道这两个人赢的场数
不知道是哪个人先发球
让你输出发球失误可能的次数

思路:
找规律…
写一页草稿纸差不多
就分a+b为奇数的情况与a+b为偶数的情况
奇数的时候比较明显
比如a+b=5的时候
a=5 b=0时答案为2 3
a=4 b=1时答案为1 2 3 4
a=3 b=2时答案为0 1 2 3 4 5
之后同理
奇数的时候是从中间向两边延伸的
找到两个数最大值与n的差值然后长度就是(n-max(a,b)+1)*2
第一个数就是n/2-(n-max(a,b))(找到n/2后减去长度的一半+1就是开头的数字
而偶数的时候比如
a+b=4
a=4,b=0时候答案为2
a=3,b=1时候答案为1 3
a=2,b=2时候答案为0 2 4
开头的第一个数数字跟奇数的时候是一样的就是n-(n-max(a,b))
不过它跳的时候是两格两格跳的
知道规律就很好写了

AC代码:

#include <iostream>

using namespace std;

int main()
{
    int t;
    cin>>t;
    while(t--){
        int a,b;
        cin>>a>>b;
        int n=a+b;
        if(n%2==1){
            int ans=2;
            int mmax=max(a,b);
            ans+=(n-mmax)*2;
            cout<<ans<<endl;
            int st=n/2-(n-mmax);
            for(int i=st;i<st+ans;i++){
                cout<<i<<' ';
            }
            cout<<endl;
        }else{
           int mmax=max(a,b);
           int ans=n-mmax+1;
           cout<<ans<<endl;
           int st=n/2-n+mmax;
           while(ans--){
            cout<<st<<' ';
            st+=2;
           }
        cout<<endl;
        }
    }
    return 0;
}

C
题目大意:
给你n个山洞
每个山洞里都有怪物
每个怪物都有一个力量值
只有你的力量值大于怪物的力量值的时候才能打败怪物
打败怪物的时候会获得一点力量值
问你至少需要多少力量值才能打败所有怪物

思路:
先记录每个山洞需要的最小力量值是多少
然后从需要最小力量值的山洞开始打,看打完这个山洞后自己的力量值够不够下一个山洞的力量值,不够就往上加
就差不多模拟的感觉
不过也可以用二分去找边界值
具体看代码

AC代码:

#include <bits/stdc++.h>

using namespace std;
struct node{
    int v,k;
}q[100010];
int sum[100010];
int main()
{
    ios::sync_with_stdio(false),cin.tie(0);
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        for(int m=0;m<n;m++){
            cin>>q[m].k;//怪物数量
            int cnt=0;//进山洞前需要的力量值
            for(int i=0;i<q[m].k;i++){
                int x;
                cin>>x;
                if(cnt+i<=x){
                    cnt=x+1-i;
                }
            }
            q[m].v=cnt;//需要的力量值
        }
        sort(q,q+n,[](node x,node y){return x.v<y.v;});//按力量值排序
        int ans=q[0].v;
        for(int i=1;i<=n;i++)sum[i]=sum[i-1]+q[i-1].k;//前缀和记录得分
        for(int i=1;i<n;i++){
            if(ans+sum[i]<q[i].v){
                ans=q[i].v-sum[i];//不够就往上加
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值