选择题+编程题 官网有: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
****************************************************************/