哈尔滨理工大学软件与微电子学院程序设计竞赛(19级新生赛)——题解

注:所有题目不要求多组输入


索引:


A. 小乐乐学编程

题目描述

小乐乐的编程老师BoBo,经常告诉小乐乐“学习编程最好的办法就是上机实践,因为你要对计算机下指令,想让计算机帮你干活,就得多和计算机‘交流’,实践才能出真知。”

输入描述

输出描述

Practice makes perfect!

题解
  • 直接输出字符串即可
AC-Code
#include<bits/stdc++.h>
using namespace std;
int main(){
	cout << "Practice makes perfect!" << endl;
}

B. 小乐乐算平均分

题目描述

小乐乐输入三科成绩,请编程帮他输出三科成绩总分及平均分。

输入描述

一行,3科成绩(浮点数),成绩之间用一个空格隔开。

输出描述

一行,总分和平均分(小数点后保留两位),用一个空格隔开。

输入样例

79.5 80.0 98.0

输出样例

257.50 85.83

题解
  • 注意小数位数
AC-Code
#include<bits/stdc++.h>
using namespace std;

int main(){
    double a,b,c;
    while(cin >> a >> b >> c){
        printf("%.2f %.2f\n", a+b+c, (a+b+c)/3);
    }
    return 0;
}

C. 小乐乐找最大数

题目描述

小乐乐获得4个最大数,请帮他编程找到最大的数。

输入描述

一行,4个整数,用空格分开。

输出描述

一行,一个整数,为输入的4个整数中最大的整数。

输入样例

5 8 2 5

输出样例

8

题解
  • 每次记录最大值即可
  • max() 返回两个参数的最大值
AC-Code
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3fffffff

int main(){
    int maxi = -INF;
    int a;
    for(int i = 0; i < 4; i++){
        cin >> a;
        maxi = max(a, maxi);
    }
    cout << maxi << endl;
    return 0;
}

D. 小乐乐是否被叫家长

题目描述

小乐乐的班级进行了一次期中考试,考试一共有3门科目:数学,语文,英语,小乐乐的班主任决定给没有通过考核的同学家长开一次家长会,考核的标准是三科平均分不低于60分,所以现在想请你帮忙算一算小乐乐会不会被叫家长。

输入描述

一行,输入三个整数(表示小乐乐的数学、语文、英语的成绩),用空格分隔。

输出描述

一行,如果小乐乐会被请家长则输出“YES”,否则输出“NO”。

输入样例

80 60 50
70 55 40

输出样例

NO
YES

题解
  • 注意输出字符串大小写即可
AC-Code
#include<bits/stdc++.h>
using namespace std;

int main(){
    double a,b,c;
    while(cin >> a >> b >> c){
        if((a+b+c)/3 < 60)
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }
    return 0;
}

E. 小乐乐转换成绩

题目描述

小乐乐输入百分制成绩,他想将成绩转换成等级制。转换规则为:90-100为’A’,80-89为’B’,70-79为’C’,60-69为’D’,59以下为’E’。如果输入的成绩不在0-100之间,输出’F’。

输入描述

一行,一个整数表示的成绩。

输出描述

一行,转换后的等级。

输入样例

78

输出样例

C

题解
  • 考察选择结构
  • 注意存在不在0 ~ 100 区间内的数
AC-Code
#include<bits/stdc++.h>
using namespace std;

int main() {

	int a;
	while (cin >> a) {
		if (a >= 90 && a <= 100)
			cout << "A" << endl;
		else if (a >= 80 && a <= 89)
			cout << "B" << endl;
		else if (a >= 70 && a <= 79)
			cout << "C" << endl;
		else if (a >= 60 && a <= 69)
			cout << "D" << endl;
		else if (a >= 0 && a <= 59)
			cout << "E" << endl;
		else
			cout << "F" << endl;
	}
	return 0;
}

F. 小乐乐算多少人被请家长

题目描述

小乐乐的班主任想统计一下班级里一共有多少人需要被请家长,三个成绩(语文,数学,外语)平均分低于60的将被请家长,小乐乐想编程帮助班主任算一下有多少同学被叫家长。

输入描述

共n+1行
第一行,输入一个数n,代表小乐乐的班级中有n个同学。
在接下来的n行中每行输入三个整数代表班级中一个同学的三科成绩(语文,数学,外语),用空格分隔。

输出描述

一行,一个整数,代表班级中需要被请家长的人数。

输入样例

3
80 100 90
40 70 65
20 84 93

输出样例

1

题解
  • 考察循环结构
  • 将问题转化为子问题(对于某一位同学平均分是否 < 60),在利用循环处理重复操作
AC-Code
#include<bits/stdc++.h>
using namespace std;
int main() {
	int n;
	cin >> n;
	int ans = 0;
	int a, b, c;
	while (n--) {
		cin >> a >> b >> c;
		if ((a + b + c) / 3 < 60)
			ans++;
	}
	cout << ans << endl;
	return 0;
}

G. 小乐乐算最高分

题目描述

小乐乐的老师BoBo想知道班级中谁的程序设计基础成绩最高,请编程帮他实现。

输入描述

共n+1行
第一行输入一个数n,代表小乐乐的班级中n个同学。
第二行输入n个数,用空格相隔,代表班级中每个人的数学成绩。

输出描述

一个整数,代表班级中最高的数学成绩。

输入样例

3
99 89 39

输出样例

99

题解
  • C题加强版
  • 动态控制循环次数
AC-Code
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3fffffff
int main() {
	int n;
	cin >> n;
	int maxi = -INF;
	int a;
	while (n--) {
		cin >> a;
		maxi = max(maxi, a);
	}
	cout << maxi << endl;
	return 0;
}

H. 小乐乐计算求和

题目描述

小乐乐想计算一下1!+2!+3!+…+n!。

输入描述

一行,一个整数n。

输出描述

一行,一个整数,表示1!+2!+3!+…+n!的结果。

输入样例

3

输出样例

9

备注

结果范围在int类型范围之内

题解
  • 分解为两个子问题
  • 1、求n!
    利用循环,每次将 j 累乘 sum(sum记录了1 * 2 * … * j-1),获得前 j 项成绩,循环结束,即可得到前 n 项成绩,即 n!
  • 2、求前 n 项和
    同上,每次将 i 累加 ans(ans 记录 1 + 2 + … + i-1)
  • 由于需要先得到某一个数的阶乘,所以需要将其放入内层循环。
AC-Code
#include<bits/stdc++.h>
using namespace std;

int main() {
	int n;
	cin >> n;
	int ans = 0;
	int sum = 1;
	for (int i = 1; i <= n; i++) {
		sum = 1;
		for (int j = 1; j <= i; j++)
			sum *= j;
		ans += sum;
	}
	cout << ans << endl;
	return 0;
}

I. 小乐乐计算函数

题目描述

小乐乐学会了自定义函数,BoBo老师给他出了个问题,根据以下公式计算m的值。

其中 max3函数为计算三个数的最大值,如: max3(1, 2, 3) 返回结果为3。

输入描述

一行,输入三个整数,用空格隔开,分别表示a, b, c。

输出描述

一行,一个浮点数,小数点保留2位,为计算后m的值。

输入样例

1 2 3

输出样例

0.30

题解
  • 按照公式进行计算即可
  • 注意小数位数
AC-Code
#include<bits/stdc++.h>
using namespace std;

int main() {
	double a, b, c;
	cin >> a >> b >> c;
	double ans = max(a + b, max(b, c)) / (max(a, max(b + c, c)) + max(a, max(b, b + c)));
	printf("%.2f\n", ans);
	return 0;
}

J. 小乐乐查找数字

题目描述

给定n个整数和一个整数x,小乐乐想从n个整数中判断x出现几次,请编程帮他实现。

输入描述

共3行
第一行,一个整数,表示n(1 <= n <= 100)。
第二行,共输入n个整数,两个整数之间用空格分隔。
第三行,输入一个整数,表示要查找的整数x。

输出描述

一行,表示整数x出现的次数。

输入样例

5
1 1 2 1 3
1

输出样例

3

题解
  • 先利用数组存储所有的数
  • 利用循环遍历所有元素,如果遇到待查找元素,则使计数器 ans + 1
AC-Code
#include<bits/stdc++.h>
using namespace std;

#define MAXN 105
int a[MAXN];
int main() {
	int n;
	cin >> n;
	for (int i = 0; i < n; i++) 
		cin >> a[i];
	int key;
	cin >> key;
	int ans = 0;
	for (int i = 0; i < n; i++) 
		if (a[i] == key)
			ans++;
	cout << ans << endl;
	return 0;
}

K. 小乐乐与进制转换

题目描述

小乐乐在课上学习了二进制八进制与十六进制后,对进制转换产生了浓厚的兴趣。因为他的幸运数字是6,所以他想知道一个数表示为六进制后的结果。请你帮助他解决这个问题。

输入描述

输入一个正整数n (1 ≤ n ≤ 109)

输出描述

输出一行,为正整数n表示为六进制的结果

输入样例

6
120

输出样例

10
320

题解
  • 除K取余,倒着写
  • 数组a模拟栈(FILO先进后出),k 记录栈顶元素下标
AC-Code
#include<bits/stdc++.h>
using namespace std;

int main(){
	int count, n, k = 0, a[15];
	scanf("%d", &n);
	k = 0;
	while (n){
		a[k] = n % 6;	// 入栈
		n = n / 6;
		k++;	//	栈顶指针移动
	}
	while (k--)	//	循环出栈
		printf("%d", a[k]);
	return 0;
}

L. 小乐乐求和

题目描述

小乐乐最近接触了求和符号Σ,他想计算在这里插入图片描述的结果。但是小乐乐很笨,请你帮助他解答。

输入描述

输入一个正整数n (1 ≤ n ≤ 109)

输出描述

输出一个值,为求和结果。

输入样例

1
10

输出样例

1
55

题解
  • 数学公式
  • 注意数据范围
AC-Code
#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
int main() {
	ll n;
	cin >> n;
	cout << (n * (n + 1)) / 2 << endl;
	return 0;
}

M. 小乐乐定闹钟

题目描述

小乐乐比较懒惰,他现在想睡觉,然后再去学习。他知道现在的时刻,以及自己要睡的时长,想设定一个闹钟叫他起床学习,但是他太笨了,不知道应该把闹钟设定在哪个时刻,请你帮助他。(只考虑时和分,不考虑日期)

输入描述

输入现在的时刻以及要睡的时长k(单位:minute),中间用空格分开。
输入格式:hour:minute k(如 hour 或 minute 的值为1,输入为1,而不是01)
(0 ≤ hour ≤ 23,0 ≤ minute ≤ 59,1 ≤ k ≤ 109)

输出描述

对于每组输入,输出闹钟应该设定的时刻,输出格式为标准时刻表示法(即时和分都是由两位表示,位数不够用前导0补齐)。

输入样例

0:0 100
1:0 200

输出样例

01:40
04:20

题解
  • 先将时间全部处理为分钟数,然后在分别转换为小时数、分钟数
  • 注意hour <= 23,需要对 24 取模
  • 前导 0 补齐(%kmd,m设置宽度,k设置不足时前补内容)
AC-Code
#include<bits/stdc++.h>
using namespace std;

int main() {
	int a, b, c, sum;
	scanf("%d:%d%d", &a, &b, &c);
	sum = a * 60 + b + c;
	printf("%02d:%02d\n", sum / 60 % 24, sum % 60);
}

N. 小乐乐排电梯

题目描述

小乐乐学校教学楼的电梯前排了很多人,他的前面有n个人在等电梯。电梯每次可以乘坐12人,每次上下需要的时间为4分钟(上需要2分钟,下需要2分钟)。请帮助小乐乐计算还需要多少分钟才能乘电梯到达楼上。(假设最初电梯在1层)

输入描述

输入包含一个整数n (0 ≤ n ≤ 109)

输出描述

输出一个整数,即小乐乐到达楼上需要的时间。

输入样例

1
12

输出样例

2
6

题解
  • k 记录还有多长时间小乐乐能上电梯
  • 小乐乐上电梯后需要2分钟到达
AC-Code
#include<bits/stdc++.h>
using namespace std;

int main(){
	int n, k;
	scanf("%d", &n);
	k = n / 12 * 4;
	printf("%d", k + 2);
}


O. 小乐乐与欧几里得

题目描述

小乐乐最近在课上学习了如何求两个正整数的最大公约数与最小公倍数,但是他竟然不会求两个正整数的最大公约数与最小公倍数之和,请你帮助他解决这个问题。

输入描述

每组输入包含两个正整数n和m。(1 ≤ n ≤ 109,1 ≤ m ≤ 109)

输出描述

对于每组输入,输出一个正整数,为n和m的最大公约数与最小公倍数之和。

输入样例

10 20
15 20

输出样例

30
65

题解
  • 辗转相除法求最大公约数
  • m * n / gdc(m, n) 即为 m 和 n 的最小公倍数
AC-Code
#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
LL gcd(LL a, LL b) {
	return b == 0 ? a : gcd(b, a % b);
}
int main() {
	LL a, b;
	cin >> a >> b;
	cout << gcd(a, b) + a * b / gcd(a, b);
}

P. 小乐乐改数字

题目描述

小乐乐喜欢数字,尤其喜欢0和1。他现在得到了一个数,想把每位的数变成0或1。如果某一位是奇数,就把它变成1,如果是偶数,那么就把它变成0。请你回答他最后得到的数是多少。

输入描述

输入包含一个整数n (0 ≤ n ≤ 109)

输出描述

输出一个整数,即小乐乐修改后得到的数字。

输入样例

222222
123

输出样例

0
101

题解
  • 直接模拟即可
  • 注意去除前导 0
AC-Code
#include<bits/stdc++.h>
using namespace std;

int main() {
	string s;
	cin >> s;
	for (int i = 0; i < s.length(); i++) {
		if ((s[i] - '0') & 1)
			s[i] = '1';
		else
			s[i] = '0';
	}
	int i = 0;
	while (s[i] == '0')	// 去除前导零
		i++;
	if (i == s.length()) // 特殊处答案为0的情况
		cout << 0 << endl;
	for (; i < s.length(); i++)
		cout << s[i];
}

Q. 小乐乐走台阶

题目描述

小乐乐上课需要走n阶台阶,因为他腿比较长,所以每次可以选择走一阶或者走两阶,那么他一共有多少种走法?

输入描述

输入包含一个整数n (1 ≤ n ≤ 30)

输出描述

输出一个整数,即小乐乐可以走的方法数。

输入样例

2
10

输出样例

2
89

题解
  • 此题是经典的动态规划,但是由于本题数据范围(太小了),直接(暴力)采用优雅的递推公式
  • 如果数据范围扩大,就变成了经典的DP。可以利用记忆化搜索、DP方程解决
  • 注意初始化边界 a[0] = a[1] = 1
AC-Code
#include<bits/stdc++.h>
using namespace std;

int main() {
	int i, n, a[40];
	a[0] = a[1] = 1;
	for (i = 2; i < 35; i++)
		a[i] = a[i - 1] + a[i - 2];
	scanf("%d", &n);
	printf("%d\n", a[n]);
	return 0;
}

R. 小乐乐与序列

题目描述

老师给了小乐乐一个正整数序列,要求小乐乐把这个序列去重后按从小到大排序。但是老师给出的序列太长了,小乐乐没办法耐心的去重并排序,请你帮助他。

输入描述

第一行包含一个正整数n,表示老师给出的序列有n个数。接下来有n行,每行一个正整数k,为序列中每一个元素的值。(1 ≤ n ≤ 105,1 ≤ k ≤ n)

输出描述

输出一行,为去重排序后的序列,每个数后面有一个空格。

输入样例

4
2 2 1 1
5
5 4 3 2 1

输出样例

1 2
1 2 3 4 5

题解
  • 数组排序去重
  • 利用强大的sort函数排序(懒人必备),然后利用uniqe去重
  • 或者排序之后,对于每个数设置一个标志位,输出之前判断一下
AC-Code
#include<bits/stdc++.h>
using namespace std;

const int = MAXN = 1e5+7;
int a[MAXN];
int main() {
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)
		cin >> a[i];
	sort(a, a + n);
	int len = unique(a, a + n) - a; // 获得去重后的元素个数
	for (int i = 0; i < len; i++)
		cout << a[i] << " ";
}

S. 小乐乐与字符串

题目描述

在庆祝祖国母亲70华诞之际,老师给小乐乐出了一个问题。大家都知道China的英文缩写是CHN,那么给你一个字符串s,你需要做的是统计s中子串“CHN”的个数。
子串的定义:存在任意下标a < b < c,那么“s[a]s[b]s[c]”就构成s的一个子串。如“ABC”的子串有“A”、“B”、“C”、“AB”、“AC”、“BC”、“ABC”。

输入描述

输入只包含大写字母的字符串s。(1 ≤ length ≤ 8000)

输出描述

输出一个整数,为字符串s中字串“CHN”的数量。

输入样例

CCHNCHN
CCHNCHNCHNCHN

输出样例

7
30

题解
  • 数据范围很小,可以直接暴力枚举
  • 或者维护前 i 项的情况
AC-Code
  • 解法一:c,h,n分别记录之前有过字符的数量
#include<bits/stdc++.h>
using namespace std;

int a[8010]
int main(){
	cin >> a;
	int l = strlen(a);
	long long c = 0, h = 0, n= 0;
	for (int i = 0; i < l; i++)
		if (a[i] == 'C')
			c++;
		else if (a[i] == 'H')
			h += c;
		else if (a[i] == 'N')
			n += h;
	cout << n << endl;
}
  • 解法二:由于数据范围为8e3,可以先初始化一次,利用数组 v 记录前 i 项有几个字符C出现
  • 然后两层循环枚举所有情况,遇到字符N的时候,枚举所有出现 H 的地方,此时,字符 H 前出现的 C 的个数即为当前区间的字串数
#include<bits/stdc++.h>
using namespace std;

#define ll long long
const int MAXN = 8e3+7;
ll v[MAXN];
int main() {
	string s;
	cin >> s;
	int f = 0;
	for (int i = 0; i < s.length(); i++) {
		if (s[i] == 'C')
			v[i] = ++f;
		else
			v[i] = f;
	}
	ll ans = 0;
	for (int i = s.length() - 1; i >= 0; i--) {
		if (s[i] == 'N') {
			for (int j = i - 1; j >= 0; j--) {
				if (s[j] == 'H') {
					ans += v[j];
				}
			}
		}
	}
	cout << ans << endl;
}

T. 小乐乐与二段数题解传送门

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值