Advertisement

上海市计算机学会月赛 2022年9月月赛丙组

阅读量:

上海市计算机学会月赛 2022年9月月赛丙组

  • 本次考试题目难度较高
    • 计算矩形的周长及面积问题
    • 探讨机会成本的概念及其经济意义
    • 分析三色排序问题的时间复杂度
    • 研究阶乘结果末尾零的数量规律
    • 探讨前序遍历、中序遍历向后序遍历的转换方法

这次题目真的衡水

文章拖延了一段时间后仍未及时发布

文章拖延了一段时间后仍未及时发布

矩形的周长与面积

内存配置: 256兆字节
时间配置: 1秒
题目要求
请根据给定的矩形长度设为a、宽度设为b,请求输出该矩形所对应的周长与面积计算结果。

输入格式
两个整数表示 a 与 b。

单一数值代表矩形的周长

单一数值代表矩形的周长

数据范围
1≤a,b≤10000

样例数据
输入:
3 2
输出:
10
6
输入:
12 3
输出:
30
36
分析:
不分析

复制代码
    #include <bits/stdc++.h>
    using namespace std;
    long long a, b;
    int main() {
    	cin >> a >> b;
    	cout << 2 * (a + b) << endl << a*b;
    	return 0;
    }

机会成本

内存占用上限设定为256 MB

用一个整数n来表示
接下来的n行
每个后续的输入包含两个整数a_ib_i

输出格式
单个整数:表示最大的分数之和

数据范围
对于 30% 的数据,1≤n≤5,000;
对于 60% 的数据,1≤n≤20,000;
对于 100% 的数据,1≤n≤500,000;
0\leq b_i\leq a_i\leq 4000
样例数据
输入:
3
1 1
2 0
3 2
输出:
5
说明:
选择做好第二件事
分析:
不要想复杂,就是所有的分数加起来再加上分差最大的一门。

复制代码
    #include <iostream>
    using namespace std;
    int a, b, n, cnt[500001], sum, maxn;
    int main() {
    	cin >> n;
    	for (int i = 1; i <= n; i++) {
    		cin >> a >> b;
    		cnt[i] = a - b;
    		maxn = max(maxn, cnt[i]);
    		sum += b;
    	}
    	cout << sum + maxn << endl;
    	return 0;
    }

三色排序

内存占用: 256 Mb
运行时长: 1000 ms
题目描述
假定有 n 个整数 a_1,a_2,\dots, a_n ,每个数值属于集合 {0,1,2} ,请将其中一部分进行两两交换以实现排序后达到升序状态,请问最少需要多少次交换才能完成排序?

输入格式
第一行:单个整数表示 n
第二行:n 个整数表示 a_1,a_2,\dots, a_n

输出格式
单个整数:表示最少交换次数。

数据范围
对于 30% 的数据,1≤n≤5,000;
对于 60% 的数据,1≤n≤100,000;
对于 100% 的数据,1≤n≤1,000,000;
0\leq a_i\leq 2
样例数据
输入:
5
2 0 1 2 0
输出:
1
说明:
将第一个2与最后一个0交换即可
分析:
看一下有多少个2和0的位置错了就换过来,因为1永远要是在中间的

复制代码
    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN=1e6+1;
    int n, c[MAXN], num[3], x1, x2, e0, e1;
    int main() {
    	cin >> n;
    	for (int i = 1; i <= n; ++i) {
    		cin >> c[i];
    		++num[c[i]];
    	}
    	for (int i = 1; i <= num[0]; ++i)
    		if (c[i] == 1)
    			x1++;
    		else if (c[i] == 2)
    			x2++;
    	for (int i = num[0] + num[1] + 1; i <= n; ++i)
    		if (c[i] == 1) 
    			e1++;
    		else if (c[i] == 0)	
    			e0++;
    	cout << x1 + x2 + e1 + e0 - min(e0, x2) << endl;
    	return 0;
    }

阶乘尾数

内存限制: 256 Mb时间限制: 1000 ms
题目描述
给定一个整数 n,n 的阶乘定义为

n!=1\times 2\times \cdots \times n

请计算在 n! 的十进制表示中,末尾有多少个连续的 0?

例如 n=5,则 n!=120,末尾有 1 个 0,又12!=479001600,末尾有 2 个 0。

输入格式
单个整数表示 n。

输出格式
单个整数表示 n! 中末尾零的个数。

数据范围
满足条件的情况包括以下几种:

  • 当n在3到999之间时(即3≤n≤999);
  • 当n达到或超过1,000时(即n≥1,000);
  • 在所有情况下(即无论多大的n值);
    样例数据
    输入案例:5 对应的输出结果是1;
    另一组输入案例:12对应的输出结果为2;
    具体来说,当n=12时,其阶乘值为479,001,600。
    分析过程如下:该问题属于基础数学题型。我们需要计算的是n!中包含多少个因子5。由于每遇到一个5的倍数就会增加一个因子5,在更大的数字中则会增加更多。
复制代码
    #include <bits/stdc++.h>
    using namespace std;
    long long n;
    long long f(long long n) {
    	long long num = 0, i, j;
    	for (i = 5; i <= n; i += 5) {
    		j = i;
    		while (j % 5 == 0) {
    			++num;
    			j /= 5;
    		}
    	}
    	return num;
    }
    int main() {
    	cin >> n;
    	cout << f(n);
    	return 0;
    }

前序中序转后序

内存占用不得超过256兆字节 时间限定为1秒内

输入格式
第一部分:一个字符串表示二叉树的先序遍历;
第二部分:一个字符串表示二叉树的中序遍历。

输出格式
单独一行:一个字符串,表示二叉树的后序遍历。

数据范围
设二叉树的结点数量为 n,

针对一半的数据(50%),变量n满足条件1≤n≤10。
全部的数据(100%)则满足条件1≤n≤26。
这些样例数据包括:
输入示例包括ACE和CAE,
输出结果为CEA。
分析: 按照前中序原则进行判断根节点和子节点的位置关系。

复制代码
    #include <bits/stdc++.h>
    using namespace std;
    int cnt = 0;
    string n1, n2;
    void tree(int l, int r, char ch) {
    	for (int i = l; i < r; ++i) {
    		if (n2[i] == ch) {
    			if (l < i)
    				tree(l, i, n1[cnt++]);
    			if (i + 1 < r)
    				tree(i + 1, r, n1[cnt++]);
    			cout << ch;
    			break;
    		}
    	}
    }
    int main() {
    	cin >> n1 >> n2;
    	tree(0, n1.size(), n1[cnt++]);
    	return 0;
    }

全部评论 (0)

还没有任何评论哟~