选拔赛2题解
A B E 是简单题 ,读懂题很容易写 C D偏难,D题去年没写,现在也懒得写了,这是前几年福建的一套题,这是我们去年训练的ranklist https://vjudge.net/contest/117312#rank
删除了几道偏难题,然后换上了一些思路题
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<stdio.h> 3 #include<algorithm> 4 using namespace std; 5 6 /* 7 充电宝总共有m%的电量,n部手机各有ai的电量,求最多能把多少 8 手机电量充满 9 显然优先充多的,排个序就Ok 10 */ 11 12 int main(){ 13 int t, n, m; 14 int a[105]; 15 cin>>t; 16 while(t--){ 17 cin>>n>>m; 18 int sum=0; 19 for(int i=0;i<n;i++){ 20 cin>>a[i]; 21 a[i]=100-a[i]; 22 } 23 sort(a,a+n); 24 for(int i=0;i<n;i++) 25 if(m>=a[i]){ 26 m-=a[i]; 27 sum++; 28 } 29 cout<<sum<<endl; 30 } 31 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cmath> 3 #include<cstdio> 4 #include<algorithm> 5 using namespace std; 6 7 /* 8 判断两个圆是相交 相离 外切 内切 内含 相离 9 差不多应该是这个题意 10 很好判,大家应该都会 11 */ 12 13 double len(double x1,double y1,double x2,double y2){ 14 double dis=(x2-x1)*(x2-x1)+(y2-y1)*(y2-y1); 15 return sqrt(dis); 16 } 17 18 struct circle{ 19 double x,y,r; 20 circle(){x=y=r=0;} 21 circle(double a,double b,double c):x(a),y(b),r(c){} 22 }; 23 24 //判断相交 相离 外切 内切 内含 25 //判断相离 26 int solve(circle a,circle b){ 27 double dis=len(a.x,a.y,b.x,b.y); 28 double c=fabs(a.r-b.r),d=a.r+b.r; 29 if(dis>d) 30 return 4; 31 else if(dis==d) 32 return 3; 33 else if(dis==c) 34 return 1; 35 else if(dis<c) 36 return 0; 37 else 38 return 2; 39 } 40 41 int main(){ 42 circle a,b; 43 int t; 44 cin>>t; 45 while(t--){ 46 cin>>a.x>>a.y>>a.r>>b.x>>b.y>>b.r; 47 if(a.x==b.x&&a.y==b.y&&a.r==b.r){ 48 puts("-1"); 49 continue; 50 } 51 cout<<solve(a,b)<<endl; 52 } 53 return 0; 54 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstring> 3 #include<string> 4 #include<cstdio> 5 #include<cstdio> 6 using namespace std; 7 const int maxn=2005; 8 int dp[maxn*maxn]; 9 /* 10 这道题是我记错了,放的有点难了 11 这要涉及到位运算和动态规划了,如果你一不小心出了这道题 12 那你可是很厉害哦,中学打过noip吧 13 14 给你你长度为n的字符串,整个字符串中的字符种类是字母表的前k种 15 让你找到两个不同的连续子串 16 这两个子串满足没有重复的元素种类 17 然后求符合条件的两个字符串的长度的乘积 18 19 用dp[state]表示字母状态为state的字母种类的最大长度是多少 20 然后再求dp[state]表示字母种类状态为state及其子集的最大长度 21 然后就可以用dp[state]*dp[((1<<k)-1)^state]更新答案 22 23 */ 24 25 26 string s; 27 28 int main(){ 29 int t,n,k; 30 cin>>t; 31 while(t--){ 32 cin>>n>>k; 33 cin>>s; 34 memset(dp,0,sizeof(dp)); 35 for(int i=0;i<n;i++){ 36 int tmp=0; 37 for(int j=i;j<n;j++){ 38 tmp|=1<<(s[j]-'a'); 39 dp[tmp]=max(dp[tmp],j-i+1); 40 } 41 } 42 int ans=0; 43 int all=(1<<k)-1; 44 for(int i=0;i<=all;i++){ 45 int sup=all^i; 46 int sub=sup; 47 do{ 48 ans=max(ans,dp[i]*dp[sub]); 49 sub=(sub-1)⊃ 50 }while(sub!=sup); 51 } 52 cout<<ans<<endl; 53 } 54 return 0; 55 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 /* 5 共有n种球,每种球有ai个,球都放在箱子中 6 每次主持人拿出一个球问你是什么颜色,直到箱子为空 7 输出你最多清楚的知道球颜色的个数 8 显然,一直猜某一种颜色就好了 9 */ 10 11 int main(){ 12 int n,a,ans=0; 13 scanf("%d",&n); 14 while(n--)scanf("%d",&a),ans=max(ans,a); 15 printf("%d\n",ans); 16 return 0; 17 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e6+5; 4 typedef long long ll; 5 ll d[maxn]; 6 7 /* 8 某个数n的算术平方根是sqrt(n) 9 m%n就是m/n的余数 10 要找到0-(p-1)的数在%p的基础上的平方根 11 也就是说如果x*x%p=y 那么可以说x是y在模p意义下的平方根 12 如果要做,那么要介绍下同余定理 13 x*y%p=(x%p)*(y%p)%p 14 (x+y)%p=((x%p)+(y%p))%p 15 只要枚举x,记录下y的模p意义下的平方根x就好了,但是无法确定 16 枚举范围 17 如果要做,那么要介绍下同余定理 18 x*y%p=(x%p)*(y%p)%p 19 (x+y)%p=((x%p)+(y%p))%p 20 如果x>=n*p+x1 那么x*x%p就等价于x1*x1%pair 21 所以只要从0枚举到p-1就好了 22 */ 23 24 int main(){ 25 int p; 26 scanf("%d",&p); 27 for(int i=1;i<p;i++)d[i]=-1; 28 for(ll i=1;i<p;i++)d[i*i%p]=i; 29 30 for(int i=0;i<p;i++)printf("%d ",d[i]);puts(""); 31 return 0; 32 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=2e5+5; 4 typedef long long ll; 5 int l[maxn],r[maxn]; 6 /* 7 有n支队伍,组委会把每支队伍的分数都在[Ai,Bi]之间 8 组委会想让晋级的队伍更多,但是他们必须取得所有队伍的最大分 9 10 要取得所有队伍的最大分,那么就挑分数高的队伍 11 要满足取得所有分数的最大分,那么只要挑选晋级分数为[max(A),max(B)] 12 要保证队伍晋级数量最多,那么只要取max(A)为晋级分数就好了 13 那么只要Bi>=max(A)的都可以晋级 14 */ 15 16 int main(){ 17 int n,ans=0,_max=-2e9; 18 scanf("%d",&n); 19 for(int i=0;i<n;i++){ 20 scanf("%d%d",l+i,r+i); 21 _max=max(_max,l[i]); 22 } 23 for(int i=0;i<n;i++)if(r[i]>=_max)ans++; 24 printf("%d\n",ans); 25 return 0; 26 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=2e5+5; 4 typedef long long ll; 5 int a[maxn],b[maxn],c[maxn]; 6 int d[maxn]; 7 8 /* 9 n个人,每个人有3种技能值,如果一个人有2个技能值大于另一个人 10 那么这个人就获胜,保证没有平局出现,求一局都赢不了的人 11 如果不存在,那么输出0 12 13 因为没有平局出现,那么必然至多有一个人一局都赢不了 14 可以反正一下,如果存在两个人一局都赢不了,那么这两个人 15 是平局,显然和题意矛盾 16 17 如果存在的话 18 只要记录下当前一局都赢不了的人,然后和其他的人比赛, 19 那么当前人获胜,那么更新记录,最后剩下的必然是一局都赢不了的人 20 还可能不存在答案,只要让上次记录的答案的人,再和所有的人干一架 21 就行了,如果存在某次赢了,那么就是没有答案 22 23 */ 24 25 bool judge(int i,int j){ 26 int cnt=0; 27 if(a[i]>a[j])cnt++; 28 if(b[i]>b[j])cnt++; 29 if(c[i]>c[j])cnt++; 30 return cnt>=2; 31 } 32 33 int main(){ 34 int n; 35 scanf("%d",&n); 36 int flag=1; 37 for(int i=1;i<=n;i++){ 38 scanf("%d%d%d",a+i,b+i,c+i); 39 if(judge(flag,i))flag=i; 40 } 41 bool ok=1; 42 //for(int i=1;i<=n;i++)if(judge(flag,i)){ok=0;break;} 43 if(ok){ 44 puts("1"); 45 printf("%d\n",flag); 46 } 47 else puts("0"); 48 return 0; 49 }