欢迎使用本站,预祝练习时长两年半的选手们到成功! [本模块信息来自tem/def/head]

2023年 12月 GESP C++ 五级真题解析 编程题

时间:2024-05-21 11:49 作者:lizq 点击:
三、编程题(每题 25 分,共 50 分) 1、小杨的幸运数 问题描述 ⼩杨认为,所有⼤于等于 a 的完全平⽅数都是他的超级幸运数。 ⼩杨还认为,所有超级幸运数的倍数都是他的幸运数。⾃

三、编程题(每题 25 分,共 50 分)

1、小杨的幸运数

问题描述
⼩杨认为,所有⼤于等于 a 的完全平⽅数都是他的超级幸运数。
⼩杨还认为,所有超级幸运数的倍数都是他的幸运数。⾃然地,⼩杨的所有超级幸运数也都是幸运数。
对于⼀个⾮幸运数,⼩杨规定,可以将它⼀直+1,直到它变成⼀个幸运数。我们把这个过程叫做幸运化。例如,如果 a=4,那么 4 是最⼩的幸运数,⽽1 不是,但我们可以连续对 1 做 3 次+1 操作,使其变为 4,所以我们可以说,幸运化后的结果是 4。现在,⼩样给出 N 个数,请你⾸先判断它们是不是幸运数;接着,对于⾮幸运数,请你将它们幸运化。
输入描述
第⼀⾏ 2 个正整数 a,N。
接下来 N ⾏ ,每⾏⼀个正整数 x ,表⽰需要判断(幸运化)的数。

输出描述
输出 N ⾏,对于每个给定的 x ,如果它是幸运数,请输出lucky ,否则请输出将其幸运化后的结果。
特别提醒
在常规程序中,输⼊ 、输出时提供提⽰是好习惯。但在本场考试中,由于系统限定,请不要在输⼊、输出中附带任何提⽰信息。

样例输入 1

2 4
1
4
5
9

样例输出 1

4
lucky
8
lucky

样例解释 1
1 虽然是完全平⽅数,但它⼩于 a, 因此它并不是超级幸运数,也不是幸运数。将其进⾏3 次+1 操作后,最终得到幸运数 4。
4 是幸运数,因此直接输 lucky。
5 不是幸运数,将其进⾏3 次+1 操作后,最终得到幸运数8。
9 是幸运数,因此直接输出 lucky。
样例输入 2

16 11
1
2
4
8
16
32
64
128
256
512
1024

样例输出 2

16
16
16
16
lucky
lucky
lucky
lucky
lucky
lucky
lucky

数据规模
对于 30%的测试点,保证 a,x≤ 100,N ≤ 100。
对于 60%的测试点,保证 a, x≤ 106
对于所有测试点,保证 a ≤1,000,001; 保证 N ≤2x 105,保证1 ≤ x ≤1,000,001
【题目大意】给一个完全平方数的标准,推导出哪些是超级幸运数,然后判断N个数字中,哪些是超级幸运数,是的输出“lucky”,不是的输出离该数字最近的比它大的数字。
【考纲知识点】数学知识,埃筛知识,循环知识
【解题思路】完全平方数按照定义,包括 1,4,9,16,25……。超级幸运数还可以是完全平方数的倍数,因此 8,12,18……也是超级幸运数。数据范围比较大,1e6,用埃筛的模板,判断每一个数字是否是幸运数字。不是幸运数字的话,保留离它最近的幸运数字作为答案。最终完成整个查询。
【参考程序】

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <string>
#include <map>
#include <iostream>
#include <cmath>
using namespace std;
const int N = 1001*1001;
const double eps = 1e-8;
bool is_lucky[N +5];
int next_lucky[N + 5];
void init(){
	
}
int main(){
	int a, T;
	scanf("%d%d", &a, &T);
	for(int i=1; i<=N; i++){
		int t = int(sqrt(i) + eps);
		if (i >=a && t*t == i)
			is_lucky[i] = 1;
		if(! is_lucky[i])
			continue ;
			
		for(intj = i+i; j <= N; j += i)
			is_lucky[j] = 1;
	}
	for(int i = N; i; i--)
		next_lucky[i] = is_lucky[i] ? i : next_lucky[i + 1];
	while(T --){
		int x;
		scanf("%d",&x);
		if(is_lucky[x])
			cout << "lucky" << endl;
		else
			cout << next_lucky[x] << endl;
	}
	return 0;
}

2、烹饪问题
问题描述
有 N 种⾷材,编号从 0⾄N - 1,其中第 i 种⾷材的美味度为ai
不同⾷材之间的组合可能产⽣奇妙的化学反应。具体来说,如果两种⾷材的美味度分别为 x 和 y,那么它们的契合度为 x and y。其中,and 运算为按位与运算,需要先将两个运算数转换为⼆进制,然后在⾼位补⾜0,再逐位进⾏与运算。例如,12 与 6 的⼆进制表⽰分别为 1100 和 0110,将它们逐位进⾏与运算,得到0100,转换为⼗进制得到 4,因此 12 and 6 = 4。在 C++Pythoy中,可以直接使⽤&运算符表⽰与运算
现在,请你找到契合度最⾼的两种⾷材,并输出它们的契合度。

输入描述
第⼀⾏⼀个整数 N,表⽰⾷材的种数。
接下来⼀⾏N 个⽤空格隔开的整数,依次为 a0,… ,aN-1,表⽰各种⾷材的美味度。
输出描述
输出一行一个整数,表示最高的契合度。
特别提醒
在常规程序中,输入、输出时提供提示是好习惯。但在本场考试中,由于系统限定,请不要在输入、输出中附带任何提示信息。
样例输入 1

3
1 2 3

样例输出 1

2

样例解释 1
可以编号为 1 , 2 的⾷材之间的契合度为 2 and 3 = 2 ,是所有⾷材两两之间最⾼的契合度。
样例输入 2

5
5 6 2 10 13

样例输出 2

8

样例解释 1
可以编号为 3 4 的⾷材之间的契合度为 10 and 13 = 8 ,是所有⾷材两两之间最⾼的契合度。
数据规模
对于 40%的测试点 ,保证 N ≤ 1,000;
对于所有测试点 ,保证 N ≤ 106 ,0 ≤ ai ≤ 2,147,483,647。

【题目大意】选出 2 个数字,求出这 2 个数字与操作的最大结果是多少。
【考纲知识点】位运算知识,循环知识,排序知识
【解题思路】需要选取 2 个数字,可以用双重循环枚举这2 个数字,取最大值,最终得到答案。对于前 40%的测试点是可以的。当数据量大的时候,就超时了。我们知道,两个数字对应的二进制,位数越高是 1,越有可能是答案。所以从最高位统计,是否至少有 2 个数字最高位是 1,保存最高位结果,并且把最高位非1 的数字删去;再查询次高位是否至少有 2 个以上的数字二进制位都是1,以此类推,求出哪 2 个数字与 结果最大。利用快速排序的方法每次将剩余数字中当前考虑的位为 1 的数字放在前面,时间复杂度是 O(N*log(a_i 值的最大值))。
【参考程序】

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
using namespace std;

const int MAX_N = int(1e6)+100;

int a[MAX_N];

int sort(int l,int r,int k){
	while(l<=r){
		while((l<=r)&&(a[l] >> k & 1)) l++;
		while((l<=r)&&(!(a[r] >> k & 1))) r--;
		if(l<=r) swap(a[l++],a[r--]);
	}
	return r;
}
int main(){
	int n,j, ans=0;
	scanf("%d", &n);
	for(int i=1; i <= n;i++) scanf("%d",&a[i]);
	for(int i=31; i>=0; i--)
		if((j=sort(1,n,i)) >= 2){
		    ans = ans | 1 << i;
			n = j;
		}
	printf("%d\n", ans);
	return 0;
}


(责任编辑:lizq)
    顶一下
    (0)
    0%
    踩一下
    (0)
    0%