2021.3.3 Rating
A - A
题意:有n个学生,名字首字母相同的学生会很健谈,把学生分到两个班,使健谈的学生对数最少
题解:将首字母相同的学生尽可能的平均分到两组。
#include<iostream> #include<cstdio> using namespace std; int f(int m){ int ans=1; for(int i=m-2+1;i<=m;i++){ ans*=i; } return ans/2; } int a[27]; int main(){ string s; int n; cin>>n; for(int i=1;i<=n;i++){ cin>>s; a[s[0]-'a']++; } int sum=0; for(int i=0;i<26;i++){ sum+=f(a[i]/2)+f(a[i]-a[i]/2); } cout<<sum<<endl; return 0; }
B - B
题意:给长度为k的单词,把这个单词分成n行m列(即n*m==k),使每行每列的每个元音字母至少出现一次。如果存在这样的单词输出,如果不存在输出-1
题解:要使每行每列每个元音字母至少出现一次,n和m必须都大于等于5。若存在,第一行从a开始按照aeiou的排列顺序依次输出,第二行从e开始按照aeiou的排列顺序依次输出,第三行从i开始按照aeiou的排列顺序依次输出,以此类推。
#include<iostream> #include<cmath> #include<algorithm> #include<string> #include<cstring> using namespace std; int main(){ int n,flag=0,t; cin>>n; for(int i=5;i*i<=n;i++){ if(n%i==0&&i>=5&&n/i>=5){ flag=1; t=i; break; } } if(!flag){ cout<<"-1"<<endl; }else{ for(int i=1;i<=t;i++){ for(int j=1;j<=n/t;j++){ if(((t/n)*(i-1)+j+i-1)%5==1){ cout<<'a'; }else if(((t/n)*(i-1)+j+i-1)%5==2){ cout<<'e'; }else if(((t/n)*(i-1)+j+i-1)%5==3){ cout<<'i'; }else if(((t/n)*(i-1)+j+i-1)%5==4){ cout<<'o'; }else if(((t/n)*(i-1)+j+i-1)%5==0){ cout<<'u'; } } } } cout<<endl; return 0; }
C - C
题意:给一组数,判断有几组数符合max( |x+y| , |x-y| ) > max( |x| , |y| ),min( |x+y| , |x-y| ) < min( |x| , |y| ),
题解:假设|x|>|y|,一共有四种情况(1)x>0,y>0,若符合则x<2y(2)x>0,y<0,则x<-2y(3)x<0,y>0,则-x<2y (4)x<0,y<0,-x<-2y
即|x|<2|y|,将所有数以正数存进数组并排列,用二分的方法判断只要符合|x|<|y|便可
#include<algorithm> #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<set> using namespace std; typedef long long ll; int a[200010] ; int main(){ int n,x; cin>>n; for(int i=0;i<n;i++){ cin>>a[i]; if(a[i]<0){ a[i]=-a[i]; } } sort(a,a+n); int left=0,right=1; ll sum=0; while(right<n){ if(a[right]-a[left]<=a[left]){ sum+=right-left; right++; }else{ left++; } } cout<<sum<<endl; return 0; }

浙公网安备 33010602011771号