Codeforces Round #610 (Div. 2)

30 篇文章 0 订阅

A题:https://codeforces.com/contest/1282/problem/A

题意:多组输入,在Ox坐标系中给你一个范围a-b,给你一个点,这个点有一个半径为r的覆盖范围,问:从a->b以每秒走1个单位长度的速度,其中在走完a,b时间内,其中有多少时间未在这个站点的覆盖范围内。

思路:这道题的话,a->b的总时间是max(a,b)-min(a,b)。仅需判断站点位于ab之间还是位于ab之外就行。

AC代码:

#include <bits/stdc++.h>
typedef long long ll;
const int maxx=10010;
const int inf=0x3f3f3f3f;
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        ll a,b,x,r;
        cin>>a>>b>>x>>r;
        ll min1=min(a,b);
        ll max1=max(a,b);
        a=min1;
        b=max1;
        ll w=x-r;
        ll z=x+r;
        ll ans;
        if(z<=a||w>=b)
            ans=0;
        else
        {
            if(w<=a)
            {
                ans=min(b-a,z-a);
            }
            else if(z>=b)
            {
                ans=min(b-a,b-w);
            }
            else ans=z-w;
        }
        ans=b-a-ans;
        cout<<ans<<endl;
    }
    return 0;
}

B题:https://codeforces.com/contest/1282/problem/B2

题意:在商店买东西,商店有n个物品,每个物品有自己的价格,商店有个优惠活动,当你买恰好k个东西时可以只为其中最贵的那个付款,求有限的钱中买到的最多的物品数量,你可以多次使用优惠。

思路:这道题的话,我们把所有商品的价格排序从小到大一遍,设第i个物品的价格是a[i],Sum[i]表示购买前i个物品花费的钱,作为前缀和。可以发现当你买了当第i个物品时,那么只需要支付Sum[i-k] + a [i] 即可,因为你买了当前的物品,可以赠送k-1个,那直接贪心着把小于等于当前这个物品价格的前K-1个物品直接赠送了,只需要支付a[i]费用,再支付一下sum[i-k]即可,维护整个过程sum[i] = sum[i-k] + a[i]即可。
AC代码:

#include <bits/stdc++.h>
typedef long long ll;
const int maxx=200010;
const int inf=0x3f3f3f3f;
using namespace std;
ll a[maxx];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        ll n,p,k;
        cin>>n>>p>>k;
        for(int i=1; i<=n; i++)
            cin>>a[i];
        sort(a+1,a+1+n);
        ll ans=0;
        ll sum[n+1];
        memset(sum,0,sizeof(sum));
        sum[0]=0;
        sum[1]=a[1];
        for(int i=2; i<=k; i++)
        {
            sum[i]=sum[i-1]+a[i];
        }
        for(int i=k; i<=n; i++)
        {
            sum[i]=sum[i-k]+a[i];
        }
        for(int i=0; i<=n; i++)
        {
            if(p>=sum[i])
                ans=i;
        }
        cout<<ans<<endl;
    }
    return 0;
}

 

C题:https://codeforces.com/contest/1282/problem/C

题意:  有一个人参加考试,考试只有两种题,一种是简单题,每道题耗时固定为a;另一种是困难题,每道题耗时固定为b,保证b>a。解出一道题得分都是1。考试的规则并不只是写多少题得多少分,鼓励提前交卷。假如你没有提前交卷,那么有一部分的题目会列为“必做题”,当“必做题”的题目没有全部被完成的话,这门课就算0分;否则得到与题数相同的分数,包括“必做”和“非必做”的。

思路: 这道题的话,题意很明显,需要按题目的“必做时间”按照升序排列起来,然后贪心做,从头开始遍历每道题目的必做时间。假如遍历到第i个题了,当前时间为T,那么如果在T-1时刻交卷,首先需要把前面必须做的所有题目做完,假设这个过程花费了Ti时间,然后剩下了T - Ti的时间,那么我们就在剩下的时间内贪心着先做尽可能多剩余的简单题,再做难题,记录此时的ans,不断遍历所有题目的必须做时间到最后,也不断的更新ans的最大值。最终的ans就是答案。

AC代码:

#include <bits/stdc++.h>
typedef long long ll;
const int maxx=200010;
const int inf=0x3f3f3f3f;
using namespace std;
struct node
{
    int x;
    int y;
} edge[maxx];
bool cmp(node a,node b)
{
    if(a.y!=b.y)
        return a.y<b.y;
    return a.x<b.x;
}
int main()
{
    int tt;
    cin>>tt;
    while(tt--)
    {
        ll n,t,a,b;
        cin>>n>>t>>a>>b;
        ll cnt1=0,cnt2=0;
        for(int i=1; i<=n; i++)
        {
            int num;
            cin>>num;
            if(num==0)
                cnt1++;
            else
                cnt2++;
            edge[i].x=num;
        }
        for(int i=1; i<=n; i++)
        {
            int T;
            cin>>T;
            edge[i].y=T;
        }
        sort(edge+1,edge+1+n,cmp);
        edge[n+1].y=t+1;
        ll ans=0,c1=0,c2=0;
        for(int i=1; i<=n+1; i++)
        {
            ll tot=a*c1+b*c2;
            ll time=edge[i].y-1-tot;
            if(time>=0)
            {
                ll ta=min(time/a,cnt1-c1);
                time-=ta*a;
                ll tb=min(time/b,cnt2-c2);
                ans=max(ans,c1+c2+ta+tb);
            }
            if(edge[i].x==0)
                c1++;
            else
                c2++;
        }
        cout<<ans<<endl;
    }
    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值