2020/4/12个人赛部分解题报告和补题报告
A - Balloons
题意:一共有n个包裹,每个包裹里num个气球,把包裹分给两个人,每个人至少有一个包裹,
两个人得到的气球数量不能相等。存在这样的情况就输出其中一个人包的数量和序号
不存在将输出-1。找n个包里气球数量最小的和其他气球比较,n=1时直接输出-1。

#include<cstdio> #include<iostream> #include<cmath> using namespace std; int main(){ int n,num,min=10000000; int flag,sum=0; cin>>n; for(int i=1;i<=n;i++){ cin>>num; sum+=num; if(num<min){ min=num; flag=i; } } if(n==1){ cout<<"-1"<<endl; }else{ if(sum-min==min){ cout<<"-1"<<endl; return 0; }else{ cout<<n-1<<endl; for(int i=1;i<=n;i++){ if(i!=flag){ cout<<i<<" "; } } return 0; } } return 0; }
B - Cutting
题意:第一行给n和b,下一行给n个数ai,这n这个数中奇数和偶数的个数相同,在奇数和偶数个数相等的时候,就可以剪一个片段,
需要花费|a[i]-a[i+1]|。现在总共预算是b,让你在b预算内,尽可能的多剪片段,输出最多的剪的次数。

#include<iostream> #include<cmath> #include<cstdio> #include<algorithm> using namespace std; int main(){ int n,b,i,j=0; int a[110],c[110]; int sum1=0,sum2=0,counts=0,sum=0; cin>>n>>b; for(i=0;i<n;i++){ cin>>a[i]; } for(i=0;i<n-1;i++){ if(a[i]&1){ sum1++; }else{ sum2++; } if(sum1==sum2){ c[j++]=abs(a[i]-a[i+1]); } } sort(c,c+j); for(i=0;i<j;i++){ sum+=c[i]; if(sum<=b){ counts++; }else{ break; } } cout<<counts<<endl; return 0; }
D - Sonya and Hotels
题意:按顺序给出n个旅馆和d,要新建一些旅馆,这些旅馆跟他最近的旅馆距离为d
最左边的左边和最右边的右边都可以建,单独拿出
其他的旅馆分为左右两种情况
因为某些条件下会把某个点算重,例如下面这种a[i]右边的红点和a[i+1]左边的红点会被算重
所以左边或右边判断时去掉一个等于的判断

#include<cstdio> #include<iostream> #include<cmath> using namespace std; int main(){ int n,d; int a[110]; int i,j,counts=0; scanf("%d %d",&n,&d); for(i=1;i<=n;i++){ cin>>a[i]; } for(i=1;i<=n;i++){ if(i-1>=1&&a[i]-d>a[i-1]+d){ counts++; } if(i+1<=n&&a[i]+d<=a[i+1]-d){ counts++; } } cout<<counts+2<<endl; return 0; }
E - Sonya and Exhibition
题意:给n朵花和m个区间(l,r)这个区间的美丽程度等于玫瑰花数量乘茉莉花数量
设玫瑰花数量=x,茉莉花数量=y
根据均值不等式
(xy)max<=((x+y)/2)2
当且仅当x=y时xy取得最大值 所以要xy使最大 则x,y最相近,
又因为区间分为偶数区间和奇数区间,偶数区间时使x=y,奇数区间 x=y+1;
所以每两朵花里面有一朵玫瑰花一朵茉莉花

#include<cstdio> #include<iostream> #include<cmath> using namespace std; int main(){ int n,m,l,r; int i,j; cin>>n>>m; for(i=1;i<=m;i++){ cin>>l>>r; } for(i=1;i<=n;i++){ if(i&1){ cout<<"0"; }else{ cout<<"1"; } } cout<<endl; return 0; }
F - Sonya and Robots
题意:给你n个数,从每一个数起向后找一个数,是这两个数组成一个数对,求一个有多少个数对
记录每个数字左边有多少个不同的数字,这些左边的数字就可以和此数构成数对

#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<set> using namespace std; int a[100005],b[100005]; set<int>c; int main(){ int n,i,j; long long cnt=0; cin>>n; for(i=0;i<n;i++){ cin>>a[i]; b[a[i]]=c.size(); //记录a[i]左边有多少个不同的数 c.insert(a[i]); } for(i=0;i<=100000;i++){ cnt+=b[i]; } cout<<cnt<<endl; return 0; }