吉林大学高级语言设计2025级11.20OJ考试(上半场)
第一题:除法运算
问题描述:
给定两个整数 a 和 b,计算 a 除以 b 的结果,并将结果保留至小数点后第9位。
输入格式:
一行包含两个整数 a 和 b,用空格分隔。
输出格式:
输出一个浮点数,表示 a / b 的值,精确到小数点后9位。
数据说明:
- 变量 a 和 b 均在 int 类型可表示的范围内。
- 商 a/b 在 double 类型的表示范围内。
样例输入:
5 7
样例输出:
0.714285714
解题方法:
直接执行浮点类型转换后的除法操作,利用 printf 函数中的格式控制符 "%.9lf" 实现精度要求。
代码实现:
#include <stdio.h>
int main() {
int a, b;
scanf("%d %d", &a, &b);
double result = (double)a / b;
printf("%.9lf", result);
return 0;
}
printf
第二题:2的n次方
问题描述:
输入一个整数 n,求出 2 的 n 次幂。已知 n 小于 31,因此结果不会超出 int 范围。
输入格式:
单行输入一个整数 n。
输出格式:
输出一个整数,即 2^n 的值。
样例输入:
5
样例输出:
32
思路一:使用位移运算
由于 2 的 n 次方可通过左移操作实现(1 << n),该方式高效且简洁。
代码实现1:
#include <stdio.h>
int main() {
int n;
scanf("%d", &n);
int result = 1 << n;
printf("%d", result);
return 0;
}
1 << n
补充方法:调用数学函数
也可使用 pow(2, n),但需注意返回值为浮点型,可能涉及类型转换问题。
pow(2, n)
思路二:循环累乘法
通过初始化变量为1,连续乘以2共n次,同样可以得到正确结果。
代码实现2:
#include <stdio.h>
int main() {
int n, multiplier = 1;
scanf("%d", &n);
for(int i = 0; i < n; i++) {
multiplier *= 2;
}
printf("%d", multiplier);
return 0;
}
for
第三题:Lucky Word
题目背景:
笨小猴词汇量有限,在做英语选择题时常感困扰。他发现一种规律:若某个单词中出现最多次数的字母与最少次数的字母之间的差值是一个质数,则称其为“Lucky Word”,这种单词更可能是正确答案。
输入格式:
一个仅由小写字母组成的字符串,长度不超过100。
输出格式:
第一行:若为 Lucky Word,输出 "Lucky Word";否则输出 "No Answer"。
第二行:若是 Lucky Word,输出 maxn - minn 的具体数值;否则输出 0。
样例输入:
error
样例输出:
Lucky Word
2
解决策略:
1. 利用长度为26的数组记录每个字母的出现频次。
2. 遍历字符串完成计数。
3. 扫描计数数组,找出非零项中的最大值 maxn 和最小值 minn。
4. 计算差值 diff = maxn - minn,并判断是否为质数。
5. 根据判断结果输出对应信息。
质数判断函数说明:
对于小于等于1的数返回假;2单独处理;偶数中除2外均非质数;奇数因子只需检查到 √n 即可。
完整代码:
#include <stdio.h>
#include <string.h>
#include <math.h>
int isPrime(int n) {
if (n <= 1) return 0;
if (n == 2) return 1;
if (n % 2 == 0) return 0;
for (int i = 3; i <= sqrt(n); i += 2) {
if (n % i == 0) return 0;
}
return 1;
}
int main() {
char word[105];
int count[26] = {0};
scanf("%s", word);
int len = strlen(word);
for (int i = 0; i < len; i++) {
count[word[i] - 'a']++;
}
int maxn = 0, minn = 105;
for (int i = 0; i < 26; i++) {
if (count[i] > 0) {
if (count[i] > maxn) maxn = count[i];
if (count[i] < minn) minn = count[i];
}
}
int diff = maxn - minn;
if (isPrime(diff)) {
printf("Lucky Word\n%d", diff);
} else {
printf("No Answer\n0");
}
return 0;
}
第四题:病人排队
病人就诊顺序的安排需遵循以下规则:
- 年龄大于或等于60岁的老年人优先于非老年人就诊。
- 在老年人群体中,按照年龄从高到低排序;若年龄相同,则依照登记先后顺序(即输入顺序)决定优先级。
- 非老年人则完全按照登记的先后顺序进行就诊,不参与年龄排序。
输入说明
第一行为一个正整数n(n < 100),表示病人的总数。
接下来的n行,每行包含一个长度小于10的字符串(病人ID)和一个整数(年龄),以空格分隔。
输出说明
按照最终确定的就诊顺序,逐行输出每位病人的ID。
示例输入
5
021075 40
004003 15
010158 67
021033 75
102012 30
示例输出
021033
010158
021075
004003
102012
解题方法分析
根据题目要求,可将所有病人划分为两类:老年人(age ≥ 60)与非老年人(age < 60)。
对于老年人,需先按年龄降序排列;当年龄相同时,依据其原始输入顺序升序排序。为此,需要在数据结构中记录每个病人的输入序号。
非老年人无需排序,仅需按照其被录入系统的先后顺序直接输出即可。
实现步骤
- 定义结构体类型Patient,包含三个成员:id(病人编号)、age(年龄)、order(输入顺序)。
- 读取输入数据,并为每位病人标记其输入序号。
- 将病人分别存入两个独立数组:elderly(老年人)和young(非老年人)。
- 对elderly数组进行排序:主关键字为年龄降序,次关键字为输入顺序升序。
- 首先输出排序后的老年人名单,随后依次输出非老年人名单。
代码实现
#include <stdio.h>
#include <string.h>
// 定义病人结构体
typedef struct {
char id[11]; // 病人ID
int age; // 年龄
int order; // 登记顺序
} Patient;
int main() {
int n;
scanf("%d", &n);
Patient elderly[100]; // 存储老年人
Patient young[100]; // 存储非老年人
int e_count = 0; // 老年人数量
int y_count = 0; // 非老年人数量
// 读取并分类病人信息
for (int i = 0; i < n; i++) {
char id[11];
int age;
scanf("%s %d", id, &age);
if (age >= 60) {
strcpy(elderly[e_count].id, id);
elderly[e_count].age = age;
elderly[e_count].order = i;
e_count++;
} else {
strcpy(young[y_count].id, id);
young[y_count].age = age;
young[y_count].order = i;
y_count++;
}
}
// 使用冒泡排序对老年人按年龄降序排列
for (int i = 0; i < e_count - 1; i++) {
for (int j = 0; j < e_count - i - 1; j++) {
if (elderly[j].age < elderly[j + 1].age) {
Patient temp = elderly[j];
elderly[j] = elderly[j + 1];
elderly[j + 1] = temp;
}
}
}
// 输出排序后的老年人
for (int i = 0; i < e_count; i++) {
printf("%s\n", elderly[i].id);
}
// 按输入顺序输出非老年人
for (int i = 0; i < y_count; i++) {
printf("%s\n", young[i].id);
}
return 0;
}