题目描述
给定一个序列,能否找到一个数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就足够了,但我这段代码写的相当啰嗦,因为是根据模测当时的代码后来改的,当时还以为要用二分(现在看来是真的蠢)。
这类题,看到不要怕,多思考就会发现只是纸老虎。