CF1538补题报告(A.B.C.D.F.G.)
Codeforces Round 725 (Div. 3)
A. Stone Game
A. 石头游戏
题意
给定一个序列,每次只能删除最左边或最右边的元素,求出删除最大和最小值需要多少次删除操作。
思路
找到最大值和最小值所在的位置,取四种情况中的最小值。
代码
#include<bits/stdc++.h>
using namespace std;
int n,a[105],t,maxn=1,minna=1;
int main(){cin>>t;while(t--){cin>>n;for(int i=1;i<=n;i++){cin>>a[i];}maxn=1,minna=1;for(int i=2;i<=n;i++){if(a[i]>a[maxn]){maxn=i;}if(a[i]<a[minna]){minna=i;}}cout<<min((maxn+n-minna+1),min((minna+n-maxn+1),min(max(maxn,minna),max(n-maxn+1,n-minna+1))))<<endl;}return 0;
}
B. Friends and Candies
B. 朋友与糖果
题意
给定一个序列代表每人的糖果数量,每次操作可以将一个人的部分糖果分给另一个人,求使每个人所有的糖果均等需进行多少次操作
思路
求出平均值,并判断是否为整数,非整数直接输出-1,因为分配糖果都是从糖果多的人分给糖果少的人,所以统计有多少人的糖果大于平均值
代码
#include<bits/stdc++.h>
using namespace std;
int t,n,a[200005],b,sum;
bool fl;
int main(){cin>>t;while(t--){cin>>n;b=0,fl=0,sum=0;for(int i=1;i<=n;i++){cin>>a[i];b+=a[i];if(i>1&&a[i]!=a[i-1]){fl=1;}}if(b%n!=0){printf("-1\n");continue;}if(!fl){printf("0\n");continue;}b/=n;for(int i=1;i<=n;i++){if(b<a[i]){sum++;}}printf("%d\n",sum);} return 0;
}
C. Number of Pairs
C. 对数
题意
给定一个序列和l,r,求在序列中有多少对数的和在[l,r]这个区间内
思路
首先将此序列排序,然后遍历数对的第一个数,二分查找第二个数的区间,输出所有区间的和
代码
#include<bits/stdc++.h>
using namespace std;
long long t,n,a[200005],b,sum,l,r,la,ra;
bool fl;
int main(){cin>>t;while(t--){cin>>n>>l>>r;for(int i=1;i<=n;i++){cin>>a[i];}sort(a+1,a+n+1);sum=0;for(int i=1;i<=n;i++){sum+=upper_bound(a+1+i,a+n+1,r-a[i])-lower_bound(a+1+i,a+n+1,l-a[i]);}printf("%lld\n",sum);} return 0;
}
D. Another Problem About Dividing Numbers
D. 关于除法的另一个问题
题意
给定两个整数以及操作数k,每次操作可以使a或b除以一个数,问是否可以在除以一个数k次操作后使得a=b
思路
质因数之和即操作的最大值,所以此题只需求二数的质因数个数之和是否大于k即可,但是如果a、b不成倍数关系且k=1,输出NO
代码
#include<bits/stdc++.h>
using namespace std;
long long ans,t,a,b,k;
int fenjie(int a){int sum=0;for(int i=2;i*i<=a;i++){while(a%i==0){a/=i;sum++;}}if(a>1){sum++;}return sum;
}
int main(){cin>>t;while(t--){cin>>a>>b>>k;int ka=fenjie(a),kb=fenjie(b);if(k==1){if((a%b==0||b%a==0)&&a!=b){printf("YES\n");}else{printf("NO\n");}}else{if(ka+kb>=k){printf("YES\n");}else{printf("NO\n");}}}return 0;
}
F. Interesting Function
F. 有趣的函数
题意
给定两个正整数,使第一个数不断加一,一直加到第二个数,求出此过程中变化的位数的总数
思路
l,r每次去掉个位,遍历所有位,求r-l的总和
代码
#include<bits/stdc++.h>
using namespace std;
long long ans,t,a,b;
int main(){cin>>t;while(t--){cin>>b>>a;ans=0;while(a!=0){ans+=a-b;a/=10,b/=10;}printf("%lld\n",ans);} return 0;
}
G. Gift Set
G. 礼品套装
题意
给定有x个红糖,y个蓝糖,由它们组成多个礼品盒,要求每个礼品盒内必须要有a个红糖b个蓝糖或者是a个蓝糖b个红糖,问最多能组成多少个礼品盒
思路
利用二分查找, m i d mid mid 为礼品盒数,其中要保证红糖数量的最大值不小于蓝糖数量的最小值
代码
#include<bits/stdc++.h>
using namespace std;
long long t,x,y,a,b;
bool check(int mid){int l=ceil(1.0*(x-b*mid)/(a-b));int r=floor(1.0*(y-a*mid)/(b-a));l=max(l,0);r=min(mid,r);return l<=r;
}
int main(){cin>>t;while(t--){cin>>x>>y>>a>>b;if(a==b){printf("%lld\n",min(x/a,y/a));continue;}if(x>y){swap(x,y);}if(a>b){swap(a,b);}int l=0,r=y;while(l<r){int mid=(l+r+1)/2;if(check(mid)){l=mid;}else{r=mid-1;}}printf("%lld\n",l);}return 0;
}