Codeforces Round #698 (Div. 2) C and D

C. Nezzar and Symmetric Array

构造,从d数组可以从大往小构造唯一的a数组。
eg:\(a[ ]={-z,-y,-x,x,y,z},d[ ]=[i,i,j,j,k,k]\)(已经排好序且合法),从最大的k开始可以构造出\(z\)\(-z\),因为其他任何数与\(z\)\(-z\)的距离之和都为\(2*z\),易知\(z=k/(2*n)\),这样就把z和-z确定下来了。

然后对于第二大的数\(j\),它所对应的\(y\)\(-y\)只有与\(z\)\(-z\)连接时权值为\(2*z\),其他时候都为\(2*y\),因此把2*z减掉(这样\(j==y*(2*n-2)\)了)就可以用刚刚提到的确定d中最大数对应a的方法去求。

以此类推,对每一个d数组中的数d[x],需要先让\(d[x]-=2*(d[x+1]/cnt[x+1]+d[x+2]/cnt[x+2]...+d[n]/cnt[n])\),然后检查\(d[x]\)是否大于\(0\)并且对应的\(a=d[x]/cnt[x]\)未出现过。

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define fastio ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
double pi = acos(-1);
const double eps = 1e-9;
const int inf = 1e9 + 7;
const int maxn = 2e5 + 10;
ll mod = 1000000007;

bool check(vector<ll>& a)
{
	int len = a.size();
	if (len % 2 == 0)return 0;
	for (int i = 1; 2 * i < len; i++)
		if (a[2 * i] != a[2 * i - 1])
			return 0;
	return 1;
}

map<ll, ll>mp;

int main()
{
	fastio;
	int t;
	cin >> t;
	while (t--)
	{
		mp.clear();
		int n;
		cin >> n;
		vector<ll>d(2 * n + 1);
		for (int i = 1; i <= 2 * n; i++)
			cin >> d[i];
		sort(d.begin() + 1, d.end());
		if (!check(d))
		{
			cout << "NO" << endl;
			continue;
		}
		for (int i = 1, j = 1; i <= n; i++, j += 2)
			d[i] = d[j];
		ll tmp = 0, cnt = 2 * n;
		bool flag = 1;
		for (int i = n; i >= 1; i--)
		{
			d[i] -= tmp;
			//cout << d[i] << " ";
			if (d[i] % cnt != 0 || d[i] <= 0 || mp[d[i] / cnt])
			{
				flag = 0;
				break;
			}
			mp[d[i] / cnt] = 1;
			tmp += 2 * (d[i] / cnt);
			cnt -= 2;
		}
		if (flag)
			cout << "YES" << endl;
		else cout << "NO" << endl;
	}
	return 0;

}

D - Nezzar and Board

\(2*x-y\):假设\(y=x+z\),则\(2*x-y=x-z\),即每次选择两个数\(x\)\(y\)\(y\)都会以\(x\)为轴进行翻转。

②先以k为原点,确定每个点的位置。已有数(已排序)有n-1个相互之间的距离,他们通过上述操作可以凑出的最小值为所有距离gcd在一起(更相减损的推广,这个值是可以凑出所有这些值更相减损能凑出的数的),然后去遍历一发看看有没有数可以被这个数整除。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define fastio ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
double pi = acos(-1);
const double eps = 1e-9;
const int inf = 1e9 + 7;
const int maxn = 2e5 + 10;
ll mod = 1000000007;

ll gcd(ll a, ll b){ return b ? gcd(b, a % b) : a; }

int main()
{
	fastio;
	int t;
	cin >> t;
	while (t--)
	{
		ll n, k;
		cin >> n >> k;
		vector<ll>a(n + 1);
		for (int i = 1; i <= n; i++)cin >> a[i], a[i] -= k;
		sort(a.begin() + 1, a.end());
		ll g = a[2] - a[1];
		for (int i = 3; i <= n; i++)
			g = gcd(g, a[i] - a[i - 1]);
		bool flag = 0;
		for (int i = 1; i <= n; i++)
			if (a[i] % g == 0)
			{
				flag = 1;
				break;
			}
		if (flag)
			cout << "YES" << endl;
		else cout << "NO" << endl;
	}
	return 0;

}

posted @ 2021-01-30 23:54  Lecoww  阅读(73)  评论(0编辑  收藏  举报