[GESP202403 五级] B-smooth 数

视频讲解:[GESP202403 五级] B-smooth 数-信息学奥赛GESP等级考试真题解析

一、原题

题目描述

小杨同学想寻找一种名为 B-smooth 数的正整数。

如果一个正整数的最大质因子不超过 B,则该正整数为 B-smooth 数。小杨同学想知道,对于给定的 n和 B,有多少个不超过 n 的 B-smooth 数。

输入格式

第一行包含两个正整数 n 和 B,含义如题面所示。

输出格式

输出一个非负整数,表示不超过 n 的 B-smooth 数的数量。

输入输出样例

输入 #1

10 3

输出 #1

7

说明/提示

数据规模与约定

子任务得分n≤B
13010^{3}1 ≤ B ≤ 10^{3}
23010^{6}n​ ≤ B ≤ 10^{6}
34010^{6}1 ≤ B ≤ 10^{6}

对全部的测试数据,保证 1 ≤ n , B ≤ 10^{6}

二、做题思路

1)填充数据

//1)确定范围n,条件b
int n,b;
cin>>n>>b;

2)埃筛求出最大质因子

//2.1)最小质数2开始 
for(int i=2;i<=n;i++){
	//2.2)是质数 
	if(gpf[i]==0){
		//2.3)把当前质数的所有倍数 标记因子 
		for(int j=i;j<=n;j+=i){
			gpf[j]=i;
		} 
	}
}

3)计算B-smooth

//3)计算B-smooth
int B_smooth=0;
for(int i=1;i<=n;i++){
	if(gpf[i]<=b) B_smooth++;
}
cout<<B_smooth;

三、答案

#include<bits/stdc++.h>
using namespace std;
int gpf[1000010]={0,1};
int main(){
	//1)确定范围n,条件b
	int n,b;
	cin>>n>>b;
	//2)埃筛求出最大质因子
	//2.1)最小质数2开始 
	for(int i=2;i<=n;i++){
		//2.2)是质数 
		if(gpf[i]==0){
			//2.3)把当前质数的所有倍数 标记因子 
			for(int j=i;j<=n;j+=i){
				gpf[j]=i;
			} 
		}
	}
	//3)计算B-smooth
	int B_smooth=0;
	for(int i=1;i<=n;i++){
		if(gpf[i]<=b) B_smooth++;
	}
	cout<<B_smooth;
} 

在解决成绩排序问题时,尤其是针对 **GESP202403 五级** 的题目要求,需要实现多级排序规则,并且保留原始输入顺序以处理并列排名的情况。可以使用结构体(或类)来封装学生的成绩信息,并通过自定义比较函实现多级排序逻辑。 ### 数据结构设计 定义一个 `Student` 结构体,用于存储每位学生的成绩信息以及计算出的总分: ```cpp struct Student { int math; // 学成绩 int chinese; // 语文成绩 int english; // 英语成绩 int total; // 总分 int index; // 输入顺序(用于保留原始索引) // 构造函 Student(int m, int c, int e, int idx) : math(m), chinese(c), english(e), index(idx) { total = m + c + e; } }; ``` ### 多级排序规则 排序的优先级如下: 1. **总分降序**(总分高的排在前面) 2. **语文与学成绩之和降序** (总分相同时,语文+学成绩高的优先) 3. **语文与学中的最高分降序** (若语之和也相同,则取语文和学中的最高分进行比较) 4. **原始输入顺序升序** (若以上条件都相同,则按照输入顺序排序) 对应的比较函如下: ```cpp bool cmp(const Student& a, const Student& b) { if (a.total != b.total) { return a.total > b.total; } int a_cm = a.chinese + a.math; int b_cm = b.chinese + b.math; if (a_cm != b_cm) { return a_cm > b_cm; } int a_max = max(a.chinese, a.math); int b_max = max(b.chinese, b.math); if (a_max != b_max) { return a_max > b_max; } return a.index < b.index; } ``` ### 完整程序示例 ```cpp #include <iostream> #include <vector> #include <algorithm> using namespace std; struct Student { int math; int chinese; int english; int total; int index; Student(int m, int c, int e, int idx) : math(m), chinese(c), english(e), index(idx) { total = m + c + e; } }; bool cmp(const Student& a, const Student& b) { if (a.total != b.total) { return a.total > b.total; } int a_cm = a.chinese + a.math; int b_cm = b.chinese + b.math; if (a_cm != b_cm) { return a_cm > b_cm; } int a_max = max(a.chinese, a.math); int b_max = max(b.chinese, b.math); if (a_max != b_max) { return a_max > b_max; } return a.index < b.index; } int main() { int n; cin >> n; vector<Student> students; for (int i = 0; i < n; ++i) { int m, c, e; cin >> m >> c >> e; students.emplace_back(m, c, e, i); } sort(students.begin(), students.end(), cmp); for (const auto& s : students) { cout << s.math << " " << s.chinese << " " << s.english << endl; } return 0; } ``` ### 程序说明 - 使用 `vector<Student>` 存储所有学生对象。 - 在排序前,每个学生对象都记录了原始输入顺序 `index`。 - 使用 `sort` 函配合自定义比较函 `cmp` 完成多级排序。 - 输出按排序后的顺序输出各科成绩。 该算法的时间复杂度为 **O(n log n)**,适用于中等规模的据排序需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值