CodeForces - 1478C - Nezzar and Symmetric Array (思维+规律)

Nezzar and Symmetric Array

题意

2 n 2n 2n不同的整数 对于每个 1 ≤ i ≤ 2 n 1\leq i \leq 2n 1i2n 都存在 1 ≤ j ≤ 2 n 1\leq j \leq 2n 1j2n 使得 a i = − a j a_i = -a_j ai=aj

d i = ∑ j = 1 2 n ∣ a i − a j ∣ d_i = \sum_{j = 1}^{2n}{|a_i - a_j|} di=j=12naiaj 给你 d d d 问是否存在符合条件的原数组

思路

举个例子 − 4 , − 3 , − 2 , − 1 , 1 , 2 , 3 , 4 -4 ,-3,-2,-1,1,2,3,4 4,3,2,1,1,2,3,4 可以发现规律 :一个数到一个较小的数和这个较小的数的相反数的距离是自身的两倍 比如 4 到 -3 和 4 到 3 距离为 8

并且一个绝对值较小的数和两个绝对值比它大的正负数的距离和 = 二倍大数的绝对值

所以可以从大到小考虑依次还原数组 判断是否符合条件即可 又发现了一个规律

首先记录 d d d数组中每个数出现的次数 稍微想一下可以知道 一个数肯定是两个两个出现 并且是偶数

s u m sum sum 记录 当前数到比它绝对值大的数的距离 t . f i r s t t.first t.first 减去 s u m sum sum 后得到的为 当前数到所有绝对值小于等于自己的数(这样的数有n个 每次找到后 n–)的距离 可以得到 x x x = ( t . f i r s t − s u m ) /   2   /   n = (t.first - sum) / \ 2 \ / \ n =(t.firstsum)/ 2 / n

记录上一个找到的数为 l a s las las 因为是从大到小找且找正的那个 所以 如果 x > = l a s    ∣ ∣    x < = 0 x >= las \ \ || \ \ x <= 0 x>=las    x<=0 就不合题意了

代码

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
//#define mod 1000000007
using namespace std;

typedef  long long LL;
typedef pair<int, int>PII;
inline LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a; }
const int N = 200010;

int n;
LL a[N];

bool cmp(LL a, LL b) {
	return a > b;
}

void solve() {
	bool flag = true;
	cin >> n;

	map<LL, LL, greater<LL>>mp;

	for (int i = 1; i <= 2 * n; ++i) {
		cin >> a[i];
		mp[a[i]]++;
	}
	LL las = LLONG_MAX;
	LL sum = 0;
	for (auto &t : mp) {
		//cout << "t.first == " << t.first << endl;
		if (t.second != 2) {
			flag = false;
			break;
		}
		else if (t.first & 1) {
			flag = false;
			break;
		}
		else {
			if (((t.first - sum) / 2) % n) {
				flag = false;
				break;
			}

			LL x = (t.first - sum)/ 2 / n;
			//cout << "x == " << x << endl;
			if (x <= 0 || x >= las) {
				flag = false;
				break;
			}
			n--;
			sum += 2 * x;
			las = x;
		}
	}
	if (flag)puts("YES");
	else puts("NO");
}

int main() {
	int t; cin >> t;
	while (t--)
		solve();

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zzqwtc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值