代码改变世界

PTA算法每日三题 - 详解

2025-11-25 08:16  tlnshuju  阅读(0)  评论(0)    收藏  举报

1077 互评成绩计算

在浙大的计算机专业课中,经常有互评分组报告这个环节。一个组上台介绍自己的工作,其他组在台下为其表现评分。最后这个组的互评成绩是这样计算的:所有其他组的评分中,去掉一个最高分和一个最低分,剩下的分数取平均分记为 G1​;老师给这个组的评分记为 G2​。该组得分为 (G1​+G2​)/2,最后结果四舍五入后保留整数分。本题就要求你写个程序帮助老师计算每个组的互评成绩。

输入格式:

输入第一行给出两个正整数 N(> 3)和 M,分别是分组数和满分,均不超过 100。随后 N 行,每行给出该组得到的 N 个分数(均保证为整型范围内的整数),其中第 1 个是老师给出的评分,后面 N−1 个是其他组给的评分。合法的输入应该是 [0,M] 区间内的整数,若不在合法区间内,则该分数须被忽略。题目保证老师的评分都是合法的,并且每个组至少会有 3 个来自同学的合法评分。

输出格式:

为每个组输出其最终得分。每个得分占一行。

#include
#include
#include
#include
using namespace std;
int main() {
	int n, m;
	cin >> n >> m;
	for (int i = 0; i < n; i++) {
		int t;
		cin >> t;
		vector arr;
		for (int j = 1; j < n; j++) {
			int s;
			cin >> s;
			if (s >= 0 && s <= m) {
				arr.push_back(s);
			}
		}
		sort(arr.begin(), arr.end());
		int sum = 0;
		for (int i = 1; i < arr.size() - 1; i++) {
			sum += arr[i];
		}
		double ave = sum / (1.0 * (arr.size() - 2));
		int r = round((ave + t) / 2.0);
		cout << r << endl;
	}
	return 0;
}

1078 字符串压缩与解压

文本压缩有很多种方法,这里我们只考虑最简单的一种:把由相同字符组成的一个连续的片段用这个字符和片段中含有这个字符的个数来表示。例如 ccccc 就用 5c 来表示。如果字符没有重复,就原样输出。例如 aba 压缩后仍然是 aba

解压方法就是反过来,把形如 5c 这样的表示恢复为 ccccc

本题需要你根据压缩或解压的要求,对给定字符串进行处理。这里我们简单地假设原始字符串是完全由英文字母和空格组成的非空字符串。

输入格式:

输入第一行给出一个字符,如果是 C 就表示下面的字符串需要被压缩;如果是 D 就表示下面的字符串需要被解压。第二行给出需要被压缩或解压的不超过 1000 个字符的字符串,以回车结尾。题目保证字符重复个数在整型范围内,且输出文件不超过 1MB。

输出格式:

根据要求压缩或解压字符串,并在一行中输出结果。

#include
#include
using namespace std;
int main() {
	char c;
	cin >> c;
	cin.ignore();
	string s;
	getline(cin, s);
	string r;
	if (c == 'C') {
		//压缩
		for (int i = 0; i < s.size(); ) {
			int j = i + 1;
			while (j < s.size() && s[j] == s[i]) {
				j++;
			}
			if (j > i + 1) {
				r += to_string(j - i) + s[i];
			}
			else {
				r += s[i];
			}
			i = j;
		}
		cout << r << endl;
	}
	else {
		for (int i = 0; i < s.size(); ) {
			//数字和字母还有空格
			string fig="";
			while (s[i] >= '0' && s[i] <= '9') {
				fig += s[i];
				i++;
			}
			int p = 0;
			if (fig == "") {
				p = 1;
			}
			else {
				p = stoi(fig);
			}
			for (int j = 0; j < p; j++) {
				r += s[i];
			}
			i++;
		}
		cout << r << endl;
	}
	return 0;
}

1079 延迟的回文数

分数 20

作者 CHEN, Yue

单位 浙江大学

给定一个 k+1 位的正整数 N,写成 ak​⋯a1​a0​ 的形式,其中对所有 i 有 0≤ai​<10 且 ak​>0。N 被称为一个回文数,当且仅当对所有 i 有 ai​=ak−i​。零也被定义为一个回文数。

非回文数也可以通过一系列操作变出回文数。首先将该数字逆转,再将逆转数与该数相加,如果和还不是一个回文数,就重复这个逆转再相加的操作,直到一个回文数出现。如果一个非回文数可以变出回文数,就称这个数为延迟的回文数。(定义翻译自 https://en.wikipedia.org/wiki/Palindromic_number )

给定任意一个正整数,本题要求你找到其变出的那个回文数。

输入格式:

输入在一行中给出一个不超过1000位的正整数。

输出格式:

对给定的整数,一行一行输出其变出回文数的过程。每行格式如下

A + B = C

其中 A 是原始的数字,BA 的逆转数,C 是它们的和。A 从输入的整数开始。重复操作直到 C 在 10 步以内变成回文数,这时在一行中输出 C is a palindromic number.;或者如果 10 步都没能得到回文数,最后就在一行中输出 Not found in 10 iterations.

//单纯这么写过不了,大数加减
#include
#include
#include
#include
using namespace std;
//判断回文数
bool Palind(string t) {
	int i = 0;
	int j = t.size() - 1;
	while (i < j) {
		if (t[i] != t[j]) {
			return false;
		}
		i++;
		j--;
	}
	return true;
}
string add(string s1, string s2) {
	int i = s1.size() - 1;
	int j = s2.size() - 1;
	string r;
	int carry = 0;
	while (i >= 0 || j >= 0||carry>0) {
		int t = 0;
		if (i >= 0) {
			t += s1[i] - '0';
		}
		if (j >= 0) {
			t += s2[j] - '0';
		}
		t += carry;
		carry = t /10;
		t = t % 10;
		r = to_string(t) + r;
		i--;
		j--;
	}
	return r;
}
int main() {
	string n;
	cin >> n;
	if (Palind(n)) {
		cout << n<<" is a palindromic number.";
	}
	else {
		int cou = 0;
		while (!Palind(n)) {
			cou++;
			string t = n;
			reverse(t.begin(), t.end());
			string c = add(n, t);
			cout << n + " + " << t << " = " << c << endl;
			n = c;
			if (cou >= 10) {
				break;
			}
		}
		if (cou >= 10) {
			cout << "Not found in 10 iterations." << endl;
		}
		else {
			cout << n << " is a palindromic number.";
		}
	}
	return 0;
}