Nezzar and Symmetric Array
题目链接:http://codeforces.com/contest/1478/problem/C
题意:
有一个数组a,由\(2n\)个不同的整数组成,对于每个\(a_i\)都有一个\(a_j\)使得\(a_i=-a_j(1<=i,j<=2n)\)。有数组d,\(d_i=\sum _{j=1}^{2n}\left | a_i-a_j \right |\)。现在给出数组d,问存不存在对应的数组a。
思路:
可以放在数轴上观察,\(a_i\)相当于数轴上的点,\(d_i\)相当于点\(i\)到其他点的距离和。因为是对称的,所以只用考虑一边的情况就可以了。明显可以看出\(d_i\)大的点在两边,小的在中间。对于相邻两点之间的距离就可以通过他们的\(d_i\)计算出来,两点之间的距离\(x_i=\left | a_i-a_{i-1} \right |\)。
\(d_i=a_{i-1}到左边所有点的和+(n+i-1)*x_i+a_{i}到右边所有点的距离和\)
\(d_{i-1}=a_{i-1}到左边所有点的和+(n-i+1)*x_i+a_{i}到右边所有点的距离和\)
\(d_i-d_{i-1}=(2*i-2)x_i\)
就可以求出\(x_i\),当\(x_i\)不是整数时,表示不存在这样的a数组。
假设\(x_1=2a_1\)(也就是\(a_1\)点到对称点的距离),\(d_1=nx_1+2*a_1到右边所有点的距离和\),可以求出\(x_1\),\(x_1\)必须为偶数,而且必须大于0。
如果满足上面的条件时,就表示存在这样的a数组。
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define sll(a) scanf("%lld",&a)
#define sll2(a,b) scanf("%lld%lld",&a,&b)
const int maxn=1e6+10;
const int mod=1e9+7;
int d[maxn];
int st[maxn];//用来存放a1-an的到其他点的距离和
map<int,int>mp;
signed main ()
{
int t;
cin>>t;
while(t--)
{
mp.clear();
int n,cnt=0;
sll(n);
for(int i=0; i<2*n; i++)
{
sll(d[i]);
mp[d[i]]++;
if(mp[d[i]]==1)
st[++cnt]=d[i];
}
sort(st+1,st+cnt+1);
int flag=1;
for(int i=1; i<=cnt; i++)
{
if(mp[st[i]]!=2)
{
flag=0;
break;
}
}
int sum=0;//用来求a1到右边所有点的距离和
if(flag)
for(int i=cnt; i>1; i--)
{
int k=2*i-2;
int s=st[i]-st[i-1];
if(s%k)
{
flag=0;
break;
}
else
sum+=(cnt-i+1)*(s/k);
}
if((st[1]-2*sum)<=0||(st[1]-2*sum)%n||(st[1]-2*sum)/n%2)//判断x1是否可能存在
flag=0;
if(flag)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}