CSDN竞赛53期题解

文章介绍了邮电出版社系列周赛中的两道非编程和编程题目。第一题涉及统计转码后的外星信号中出现频率最高的字母,利用哈希数组和遍历实现。第二题讨论如何判断给定已排序数组是否能通过中间插入变为等差数列,通过差分数组和最大公约数计算所需插入的数字数量。
摘要由CSDN通过智能技术生成

总结

邮电出版社系列周赛第一次非编程题都做对了,可惜的是这次的奖励没有《动手学深度学习》了,编程题部分还是没有什么难度的。

题目列表

1.贝博士外星信号统计

题目描述

贝博士最近收到了一些来自外星的信号,它们看起来是一些字符。经过贝博士的转码,把这些字符用26个小写拉丁字母表
示。 贝博士叫来了助手艾小姐,请她把这些字母中出现次数最多者挑出来,并按字母表顺序排列出来(忽略空格)。

分析

签到题,定义一个存放26个小写字母出现次数的哈希数组,遍历一下字符串统计下各个字母出现的次数,同时记录下字母出现最多的次数m,最后遍历一下哈希数组,按顺序输出出现次数等于m的字母即可。

注意题目输入可能除了小写字母和空格外还有其它字符,所以统计小写字母出现次数时还是需要判断下字符是否是小写字母的。

代码

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int st[26];
int main() {
	string s;
	getline(cin,s);
	int n = s.size();
	int m = 0;
	for(int i = 0; i < n; i++) {
		if (s[i] == ' ' || s[i] < 'a' || s[i] > 'z') continue;
		int t = s[i] - 'a';
		st[t]++;
		m = max(m, st[t]);
	}
	for(int i = 0; i < 26; i++) {
		if (st[i] == m) printf("%c",'a'+i);
	}
	return 0;
}

2.等差数列

题目描述

给定一已排序的正整数组成的数组,求需要在中间至少插入多少个数才能将其补全成为一等差数列。 “在中间插入”的意思
是:不能在第一个数之前,或最后一个数之后插入数。

分析

题目没有给定数据范围以及数组的个数,经过测试数据范围不会超过十万,数组的个数没给定,对于c++选手就只能读成字符串后手动切分为数组或者使用stringstream切分了,题目输入还有待改进。

题目给了三种输出,输入已经是等差数列表示不用插入数字,输出0;在中间最少插入x个数字可构成等差数列,输出x;插入数字也构成不了等差数列的,输出“NaN”。

等差数列的性质很容易想到使用差分数组,对原数组求出差分数组后就找到了相邻元素的差值。则有以下三种情况:

  • 差分数组所有元素相等,表示已经是等差数列了,输出0;
  • 差分数组中存在0且不全为0,表示有重复元素,没法添加有限的元素使得等差数列的公差为0,输出“NaN”;
  • 差分数组中不存在0且存在不同元素,可以通过插入元素构成等差数列。

对于第三种情况,只需要求出差分数组里面所有元素的最大公约数,就知道等差数列的公差是多少了。假设公差是 t t t,原数组中末尾元素减去开始元素的差值是 m m m,则等差数列中元素个数为 m / t + 1 m / t + 1 m/t+1,再减去输入元素的个数 n n n就是需要插入的元素个数了。

比赛时最后的循环漏写了个等号,还调了会才AC,题目本身难度不大。

代码

#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int a[100005];
int gcd(int a,int b) {
	return b ? gcd(b, a % b) : a;
}
int main() {
	int n = 0;
	string s;
	getline(cin,s);
	int t = 0;
	int sz = s.size();
	for(int i = 0; i < sz; i++) {
		if (s[i] != ' ') t = t * 10 + s[i] - '0';
		else {
			a[n++] = t;
			t = 0;
		}
	}
	a[n++] = t;
	t = 1e9;
	int m = a[n-1] - a[0];
	for(int i = n - 1; i >= 1; i--) {
		a[i] = a[i] - a[i-1];
		t = min(t, a[i]);
	}
	bool flag = true;
	for(int i = 1; i < n; i++) {
		if (a[i] != t) {
			flag = false;
			break;
		}
	}
	if (flag) cout<<0<<endl;
	else if (!t) cout<<"NaN"<<endl;
	else {
		t = a[1];
		for(int i = 2; i <= n - 1; i++) {
			t = gcd(t,a[i]);
			if (t == 1) break;
		}
		int res = m / t + 1 - n;
		cout<<res<<endl;
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值