2019-ICPC沈阳站

A-Leftbest

题面描述

在这里插入图片描述
在这里插入图片描述

题解

在集合中二分查找一下第一个大于当前照片印象值的值,存在就ans累加一下,最后输出答案 ans

补充

upper_bound(begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
lower_bound(begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

lower_bound( begin,end,num,greater<type>()):从数组的begin位置到end-1位置二分查找
第一个小于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去
起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num,greater<type>() ):从数组的begin位置到end-1位置二分查找
第一个小于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址
减去起始地址begin,得到找到数字在数组中的下标。

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
set<int>s;
int val,n;
ll sum=0;
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&val);
        if(s.upper_bound(val)!=s.end())sum+=*s.upper_bound(val);
        s.insert(val);
    }
    printf("%lld\n",sum);
    return 0;
}

H-Points(签到题)

题面描述

在这里插入图片描述
在这里插入图片描述

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+7;
int a[maxn],n;
int x,y;
int main()
{
    scanf("%d",&n);
    for(int i=1;i<n;++i)
    {
        scanf("%d %d",&x,&y);
        a[x]++,a[y]++;
    }
    int ans=0;
    for(int i=1;i<=n;i++)
        if(a[i]==1) ans++;
    printf("%d\n",ans);
    return 0;
}

L-Flowers

题面描述

在这里插入图片描述
在这里插入图片描述

题解

二分,就是把数从大到小排序,维护当前每个盒子放了几朵,然后对于一个数 a i _i i > 二分的值,就给每个盒子放一朵;如果 a i _i i< 二分的值,就可以给前 a i _i i 个盒子放一朵,显然这个时候 后 n-a i _i i 个盒子还没有放,直接二分,二分最后能放多少个盒子

AC代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=3e5+10;
typedef long long ll;
int n,m;
int a[maxn];
bool check(ll lim)
{
    ll cur=0,los=0;
    for(int i=1;i<=n;i++)
    {
        ll t=a[i]>lim?lim:a[i];
        if(los+t>=lim)
        {
            cur++,t-=lim-los;
            los=min(t,los);
        }
        else los+=t;
    }
    return cur>=m;  //放的层数大于等于你需要的层数就是可行的
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        sort(a+1,a+1+n);
        reverse(a+1,a+1+n);
        ll l=0,r=1e18,ans=0;
        while(l<=r)
        {
            ll mid=l+r>>1;
            if(check(mid))l=mid+1,ans=mid;
            else r=mid-1;
        }
        printf("%lld\n",ans);
    }
}

去年沈阳那场真的难受,A和L TLE,主要还是自己菜QwQ,暑假再提升一下吧,多做做真题。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

幸愉聊信奥

谢谢亲的支持,我会继续努力啦~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值