程序设计M2补题——A-HRZ的序列

该博客讨论了一道程序设计题目,要求找到一个整数K,通过加、减K或不操作,使得序列所有元素变得相等。解题关键在于判断序列中不同数值的数量,若不超过3个,进一步验证K的存在性。博主分享了解题思路和简洁的代码实现,强调遇到复杂问题要勇于思考,简化问题核心。
摘要由CSDN通过智能技术生成

题目描述

给定一个序列,能否找到一个数K,使得这个序列中的每一个数加上(或减去)K,或者不变,最后这个序列的所有数都相等,每个数最多只能进行1次操作。

Input

输入第一行是一个正整数t表示数据组数。 接下来对于每组数据,输入的第一个正整数n表示序列a的长度,随后一行有n个整数,表示序列a 。

Output

输出共包含t行,每组数据输出一行。对于每组数据,如果存在这样的K,输出"YES",否则输出“NO”。 (输出不包含引号)

解题思路

这道题乍一看似乎有点懵(比如模测的时候),但是深入思考一下就会发现,满足这种条件的序列至多只能有三个不同的数,这样一来整个题目就简单很多了,只需要判断输入的序列中不同的数有几个(可以直接利用set,既能去重还带排序,但我写的时候傻了),如果小于3,那肯定输出“YES”,如果大于3,肯定输出“NO”,如果等于3就需要判断一下:如果最大数减去K等于中间数,并且最小数加上K等于中间数,则输出“YES”,否则输出“NO”。

实现代码

#include<iostream>
#include<algorithm>
using namespace std;

long long a[10010];

int main()
{
	int t;
	cin>>t;
	for(int i=0;i<t;++i)
	{
		int n;
		bool flag=0;
		cin>>n;
		for(int j=0;j<n;++j)
			cin>>a[j];
		sort(a,a+n);
		int cnt=1;
		long long m=a[0];
		for(int j=1;j<n;++j)
		{
			if(a[j]==m)
				continue;
			else
			{
				cnt++;
				m=a[j];
			}
			if(cnt>3)
				break;
		}
		if(cnt<3)
			cout<<"YES"<<endl;
		else if(cnt==3)
		{
			long long mina=a[0],maxa=a[n-1],mid;
			for(int j=1;j<n-1;++j)
			{
				if(a[j]>mina)
				{
					mid=a[j];
					break;
				}
			}
			long long l=1,r=maxa-mina;
			bool flag=0;
			while(l<=r)
			{
				long long k=(r+l)/2;
				if(mina+k==mid&&maxa-k==mid)
				{
					flag=1;
					break;
				}
				else if(mina+k<mid||maxa-k>mid)
					l=k+1;
				else if(mina+k>mid||maxa-k<mid)
					r=k-1;
			}
			if(flag)
				cout<<"YES"<<endl;
			else
				cout<<"NO"<<endl;
		}
		else
			cout<<"NO"<<endl;
	}
	return 0; 
}

总结

这道题其实是一道很简单的题目,但是需要思考,题目看上去似乎很难,但简化之后就发现其实只需要一个set就足够了,但我这段代码写的相当啰嗦,因为是根据模测当时的代码后来改的,当时还以为要用二分(现在看来是真的蠢)。
这类题,看到不要怕,多思考就会发现只是纸老虎。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值