[LGR-113] 洛谷7月月赛
这是我第一次参加普及月赛,所以不要在意分数(
T3本来我的错误贪心能至少骗40pts,结果我自信地提交了一个
算法,爆0..
T4我写了一个双指针,at first 我应该能有20-40pts。但是,经过我的反向优化,成功爆0
T1 gcd
给定T组数据,每一组有 \(l,r,x\) 求 \(l\) 到 \(r\) 范围内的数分别向下取整后的gcd
由于数据范围有 \(10^{18}\) 所以只能用 \(O(1)\) 的算法解决(别忘了long long)
#include<bits/stdc++.h>
using namespace std;
int t;
long long r,l,x;
int main(){
scanf("%d",&t);
for(int i=1;i<=t;i++){
scanf("%lld %lld %lld",&l,&r,&x);
int tmp = r;
bool flag=1;
if(l/x!=r/x) flag=0;
if(flag==0) printf("%d\n",1);
else if(flag==1) printf("%d\n",r/x);
}
}
T2 不等价交换法则
水题*2
因为只能买一个物品,所以排序后从后往前买就行
然后再从前往后扫一遍,尽可能买多的
点击查看代码
#include<bits/stdc++.h>
using namespace std;
int n;
long long w;
long long a[1000005];
bool cmp(long long x, long long y){
return x<y;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
scanf("%lld",&w);
sort(a+1,a+n+1,cmp);
int buy=-1;
long long now=-1;//now表示拥有的商品
for(int i=n;i>=1;i--){
if(w>=a[i]){
buy = i;
now=a[i];
break;
}
}
long long cnt=0,ans=0;
for(int i=1;i<=n;i++){
if(cnt+a[i]<=now){
ans++;
cnt+=a[i];
}
}
if((ans==0)&&(now!=-1)) ans = 1;
printf("%lld",ans);
}
T3
假设c序列是固定的,我们可以从小到大枚举数列中出现过的数 \(k\) ,显然对于剩下的数而言,一定有 \(mex \leq k\)
为了方便计算,可以直接令 \(mex=k\),更优的答案一定会覆盖上一个答案。所以我们可以 枚举+取\(max(区间长度)\)
而当c序列不固定时,只需考虑\(a_x=b_x\)时情况即可,因为显然对于不等的情况,一定可以取到 \(a_x/b_x \neq x\)。所以本质是相同的
点击查看代码
#include<bits/stdc++.h>
using namespace std;
int a[1000007];
int b[1000007];
int l[1000007];
int ans[1000007];
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",a+i);
}
for(int i=1;i<=n;i++){
scanf("%d",b+i);
}
for(int i=1;i<=n;i++){
if(a[i]!=b[i]) continue;
ans[a[i]]=max(ans[a[i]],i-l[a[i]]-1-a[i]);
l[a[i]] = i;
}
for(int i=0;i<=n;i++){
ans[i] = max(ans[i],n-l[i]-i);
}
int res=0;
for(int i=0;i<=n;i++){
res = max(res,ans[i]);
}
printf("%d",res);
}
T4
因为要使\(max-min\)最大,最优的结果一定会取到序列中的极值
因此,原式可化为\(w= \left|a_l-a_r\right|-(r-l+1)\)
而要拆绝对值,只需将序列正反分别遍历一遍,取最大值
进一步化简,可得出\(w=a_r-r-(a_l-l)-1\)
因此可以设\(c_i=a_i-i\)
对于每个枚举的\(i\),只需找到\(1到i-1\)中的最小值\(j\),计算区间贡献,取最大值即可
点击查看代码
#include<bits/stdc++.h>
using namespace std;
int a[10000007],b[10000007];
int main(){
int i,j,n,m;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
b[n-i+1] = a[i];
}
int mina = 1e10+7,minb=1e10+7,maxx=0;
for(int i=1;i<=n;i++){
a[i] -= i;
b[i] -= i;
maxx=max(maxx,a[i]-mina);
maxx = max(maxx,b[i]-minb);
mina=min(mina,a[i]);
minb=min(minb,b[i]);
}
printf("%d",maxx-1);
}

浙公网安备 33010602011771号