2024年03月GESP-5 编程题答案解析

选择题+编程题 官网有:GESP官网

编程题 1:成绩排序

知识点: 离散化

写法1: 两次结构体排序

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
 
struct stu{
    int i, j;   //  i是一开始位置, j是排名的位置 
    int a,b,c;
    int sabc, sab, mab;
}s[10009]; 
bool cmp0(stu x, stu y){
    return x.i<y.i;
}
bool cmp1(stu x, stu y){
    return x.sabc>y.sabc 
    || x.sabc==y.sabc && x.sab>y.sab
    || x.sabc==y.sabc && x.sab==y.sab && x.mab>y.mab; 
}
bool cmp2(stu x, stu y){
    return x.sabc==y.sabc && x.sab==y.sab && x.mab==y.mab;
}
int main(){
    int n; scanf("%d", &n);
    for(int i=1;i<=n;++i){
        s[i].i = i;
        scanf("%d %d %d", &s[i].a, &s[i].b , &s[i].c);
        s[i].sabc = s[i].a + s[i].b + s[i].c;
        s[i].sab  = s[i].a + s[i].b;
        s[i].mab  = max(s[i].a, s[i].b);
    }
    sort(&s[1], &s[n+1], cmp1);
    for(int i=1;i<=n;++i){
        if(cmp2(s[i], s[i-1])) s[i].j = s[i-1].j;
        else s[i].j = i;
    }
    sort(&s[1], &s[n+1], cmp0); 
    for(int i=1;i<=n;++i)
        printf("%d\n", s[i].j);
} 

写法2: 二分查找

#include<bits/stdc++.h>
using namespace std;
struct T{
    int a,b,c,sum;
    bool operator<(T stu){   //  重载运算符 
        return sum>stu.sum
        ||(sum==stu.sum&& a+b>stu.a+stu.b)
        ||(sum==stu.sum&& a+b==stu.a+stu.b&&max(a,b)>max(stu.a,stu.b));
    }
}a[10009], b[10009];
 
int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i].a>>a[i].b>>a[i].c;
        a[i].sum+=a[i].a+a[i].b+a[i].c;
        b[i] = a[i];
    }   
    sort(a+1,a+n+1);
    for(int i=1;i<=n;++i)
        printf("%d\n", lower_bound(a+1, a+n+1, b[i]) - a); 
}

编程题 2:B-smooth数

知识点: 穷举+唯一分解定理 or 动态规划+筛法


思路1

枚举[1,n]中的每一个数i,对i进行唯一分解定理…
时间复杂度: O ( n n ) O(n\sqrt{n}) O(nn )
空间复杂度: O ( 1 ) O(1) O(1)

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

int n, B, sum;
int Max(int i){
	int Maxi=1;
	for(int j=2;j*j<=i;++j)
		while(i%j==0){
			Maxi = j;
			i/=j;
		}
	if(i>1) Maxi = i;
	return Maxi;
}
int main(){
	scanf("%d %d", &n, &B);
	for(int i=1;i<=n;++i)
		if(Max(i) <= B)
			sum++;
	printf("%d", sum);
}

思路2

f [ i ] f[i] f[i]表示 i i i的最大质因子,如果转移呢?
f [ i ] = m a x ( f [ j ] , i / j ) ( i % j = = 0 ) f[i] = max(f[j], i/j) (i\%j==0) f[i]=max(f[j],i/j)(i%j==0)
i i i的质因子有很多,任意一个 j j j转移即可.

这个动态规划怎么做可以更快呢?
埃氏筛或者欧拉筛的时候转移就很快了.

时间复杂度: O ( n log ⁡ n ) O(n\log{n}) O(nlogn) 或者 O ( n ) O(n) O(n)
空间复杂度: O ( n ) O(n) O(n)

#include<cstdio>
#include<algorithm>
using namespace std;
 
const int N=1e6+10;
int Maxp[N], n, b;
int main(){
    scanf("%d %d", &n, &b);
    for(int i=2;i<=n;++i)
        if(Maxp[i]==0){
            Maxp[i] = i;
            for(int j=i*2;j<=n;j+=i)
                Maxp[j] = max(Maxp[j/i], i);            
        }
    int ans = 0;
    for(int i=1;i<=n;++i)
        if(Maxp[i]<=b) 
            ans++;
    printf("%d", ans);
}
/**************************************************************
    Problem: 2723
    User: Teacher0029 [陈老师]
    Language: C++
    Result: 正确
    Time:20 ms
    Memory:5100 kb
****************************************************************/
  • 25
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值