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,暑假再提升一下吧,多做做真题。