A. Cloudberry Jam
题目大意是说 akg的浆果和akg糖混在一起可以配出(2*a*(3/4))kg的果酱(因为蒸发掉了1/4)
而一罐果酱要3kg。给出果酱罐数n,让你求出a的值。也就是(n*3)/(2*(3/4)),化简为n*2。
#include<bits/stdc++.h>
using namespace std;
int main(){
int t;cin>>t;
while(t--){
int n;cin>>n;
cout<<n*2<<endl;
}
return 0;
}
B. Large Array and Segments
题目大意是说 给一个数组a,数组b由k个循环重复的数组a组成。
给出一个x,计算数组b中满足存在r>=l使得区间[l,r]元素和至少为x的l的数量。
令r=a[n](这样对于每个l,[l,r]区间元素和最大),从后往前一一排除元素和小于x的l;
以(a={3,4,1,2,5},k=3,x=10)为例,如图:
而从第一个满足的l开始往前的每一个元素都将满足条件。(因为递增)
考虑后缀和+二分查找
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t;cin>>t;
while(t--){
int n,k;ll x;
cin>>n>>k>>x;
int a[n+1];ll b[n+2];
for(int i=1;i<=n;i++){
cin>>a[i];
}
b[n+1]=0;
for(int i=n;i>=1;i--) b[i]=b[i+1]+a[i];
//后缀和
ll s=b[1];
//每一个数组a的总和为s
if(k*s<x){
cout<<0<<endl;continue;
}//总和小于x直接跳过
ll ans=0;int i;
for(i=0;i<k;i++){
int l=1,r=n;
int res=-1;
while(l<=r){
int mid=l+(r-l)/2;
if((b[mid]+i*s)<x) r=mid-1;
else{
res=mid;
l=mid+1;
}
}//二分找第一个满足的l,注意取边界
if(res!=-1){
ans+=res;
ans+=(ll)(k-1-i)*n;
break;
}//第一发wa是因为没开ll,警钟敲烂
}
cout<<ans<<endl;
}
return 0;
}