选拔赛2题解

A B E 是简单题 ,读懂题很容易写 C D偏难,D题去年没写,现在也懒得写了,这是前几年福建的一套题,这是我们去年训练的ranklist https://vjudge.net/contest/117312#rank

删除了几道偏难题,然后换上了一些思路题

 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 }
A
 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 }
B
 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)&sup;
50             }while(sub!=sup);
51         }
52         cout<<ans<<endl;
53     }
54     return 0;
55 }
C
 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
",ans);  
16     return 0;
17 }
E
 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 }
F
 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
",ans);
25     return 0;
26 }
G
 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
",flag);
46     }
47     else puts("0");
48     return 0;
49 }
H
原文地址:https://www.cnblogs.com/jihe/p/6661949.html