[C/C++]相等序列 - 2019校招编程刷题
参考链接
题目描述
题目给定a1,a2…an,这样一个长度为n的序列,现在你可以给其中一些元素加上一个值x(只能加一次),然后可以给另外一些值减上一个值x(只能减一次),剩下的元素不能再进行操作。问最后有没有可能找到一个值x使所有元素的值相等。
输入描述
输入第一行为一个整数k,代表有k个序列(k<100),接下来有2*k行:
偶数行为一个整数n,代表给定序列的长度(1<=n<=100,000)
奇数行包含n个元素,a1,a2…an,代表序列中的元素(0<=ai<=100,000)
输出描述
输出k行,每行一个YES或者NO
输入例子1:
1
5
1 3 3 2 1
输出例子1:
YES
思路:
- 本题是运用了数学的得知识。题目要求:数列最后的值通过+x或者-x得到一个相等的数列,当数字个数为1个或者2个的时候,一定成立。当数字个数超过2位,那这个数列就必须满足 :
- ( 最 大 值 − x = = 中 位 值 = = 最 小 值 + x ) (最大值-x == 中位值 ==最小值 + x) (最大值−x==中位值==最小值+x)
- 其实就是,数字种类最多有3种,且这三种数字满足等差数列
- 博主之前是遍历了所有输入的数字,记录输入数字的种类个数,非常复杂。突然想到c++里面有个集合set类型,需要导入
include<set>
才能使用。 - set类型就是高中数学中的集合概念,要满足确定性、无序性、不可重复性。参考链接
- 使用集合记录输入的数字串,可以通过 set.size() 轻松地得到输入数字的种类,再判断输入的数字是否是等差数列即可解决问题。
- 我的代码中还用了迭代器的相关知识:参考链接
Just show my code
代码(c++/c)
#include<iostream>
#include<set>
using namespace std;
int main(){
int k;// k个序列
cin >> k; // 每一行的元素值
int n; // 每行有n个元素
int num ;
for (int i = 0; i < k ; i++){
cin >> n;
set<int> res; // 每一行的元素,这一行元素是集合类型,每种元素只有1个,并且会排序
for(int j = 0;j<n;j++){
cin >> num;
res.insert(num);
}
set<int>::iterator it = res.begin(); //返回集合的首迭代器,即指向集合中最小元素的迭代器,时间复杂度为O(1)
string ans;
if(res.size() < 3){
ans = "YES";
} else if (res.size()==3){
if((*res.begin() + *res.rbegin()) / 2 == *(++it)){ //res.rbegin() 返回一个逆序迭代器,它指向容器res的最后一个元素
ans = "YES";
}else{
ans = "NO";
}
}else{
ans ="NO";
}
cout<< ans << endl;
}
return 0;
}
如果我的文章能帮你节约20秒,就请你为我的文章点个赞吧!