其他分享
首页 > 其他分享> > CodeTON Round 1 (Div. 1 + Div. 2, Rated, Prizes!)

CodeTON Round 1 (Div. 1 + Div. 2, Rated, Prizes!)

作者:互联网

CodeTON Round 1 (Div. 1 + Div. 2, Rated, Prizes!)

A. Good Pairs

思路:我们可以根据几何意义转化下问题:在数轴上存在一些点,能否找到两个点满足其余的点到这两个点的距离等于这两个点的距离。答案显然是数组中最大和最小的元素下标。

void solve()
{
	int n;
	cin >> n;
	for(int i = 1; i <= n; i ++ ){
		cin >> a[i];
	}
	cout << max_element(a + 1, a + 1 + n) - a << " " << min_element(a + 1, a + 1 + n) - a << endl;
}

B. Subtract Operation

思路:由于需要把数组删到只剩下最后一个元素,那么在最后一步操作的前的两个数差值一定为\(k\),那么,这两个数之前减去的所有数的和是一样的,所以只要满足这两个数一开始的差值是\(k\)即可。

void solve()
{
	cin >> n >> k;
	map<int,int>mp;
	for(int i = 1; i <= n; i ++ ){
		cin >> a[i];
		mp[a[i]] ++;
	}
	for(int i = 1; i <= n; i ++ ){
		if(mp[a[i] - k]){
			cout << "Yes" << endl;
			return;
		}
	}
	cout << "No" << endl;
	return;
}

C. Make Equal With Mod

如果原数组中没有\(1\),那么我们可以不断 \(mod\)数组中大的数把原数组都变成\(0\)。

如果数组中有\(1\),我们要使数组中所有的值都相等,只能把数组中所有的元素都变成\(1\),那么我们就需要\(mod\)上比原来的数小\(1\)的数,如果出现差值为1的两个元素,就无法实现把前者变成\(1\)。

综上:数组中有\(1\),且出现连续的元素,就是不合法,其余合法。

void solve()
{
	cin >> n;
	bool ok1 = false;
	map<int,int>mp;
	for(int i = 1; i <= n; i ++ ){
		cin >> a[i];
		mp[a[i]] ++;
		if(a[i] == 1) ok1 = true;
	}
	bool ok2 = false;
	for(int i = 1; i <= n; i ++ ){
		if(mp[a[i] - 1] || mp[a[i] + 1]){
			ok2 = true;
		}
	}
	if(ok1 && ok2){
		cout << "No" << endl;
		return;
	}
	cout << "Yes" << endl;
 
}

D. K-good

思路:把题目写成数学表达式:

\[n = x* k + \frac{(k - 1) * k }{2}, x \geq 0, k\geq 2 \]

转化为一元二次方程方程,解出来\(k\),并取正的解

\[k =\frac{1 - 2 * x + \sqrt{(2 * x - 1)^2 + 8 * n}}{2} \]

要保证\(k\)为整数,那么分子的根号算出来一定是个奇数,因为分子前面一部分是奇数,我们设:

\[\sqrt{(2 * x - 1)^2 + 8 * n} = 2 * p + 1 \]

左右平方然后进行平方差公式得到:

\[(p - x + 1) * (p + x) = 2 * n \]

我们发现等式左边是\(1\)个奇数\(1\)个偶数,奇数就是\(n\)的奇数因子,我们可以预处理出来,我们先设\(n\)的奇数因子为\(a\),有两种情况:

\[p - x + 1 = a, p + x = \frac{2 * n}{a} \]

\[p + x = a, p - x + 1 = \frac{2 * n}{a} \]

由于\(n\)和\(a\)是已知的,我们可以解出\(p\)和\(x\)。然后带入上面\(k\)的表达式,算出有\(k\)有两个结果:

\[k = a或者k = \frac{2 * n}{a} \]

我们可以发现,如果\(n\)是\(2\)的次幂,那么\(k = 1, 或者 k = 2 * n\),\(k\)不合法。

由于第一个式子中\(x \geq 0\),我们可以对这个式子进行放缩:

\[n \geq \frac{(k - 1) * k }{2}, x \geq 0, k\geq 2 \]

为了更加容易满足这个式子,\(k\)应该越小越好,所以,\(k\)取两个值的最小值即可。

void solve()
{
	cin >> n;
	if(n % 2 == 1){
		cout << 2 << endl;
		return;
	}
	LL qwq = n * 2;
	while(n % 2 == 0)  n /= 2;
	if(n == 1){
		cout << "-1" << endl;
		return;
	}
	cout << min(n, qwq / n) << endl;
}

E. Equal Tree Sums

思路:我们先统计出所有结点的度数,然后对树进行黑白染色,使得删除任意一个结点,剩余的连通块的权值总和为\(-1\)。

void dfs(int x, int u){
	if(u == 1) ans[x] = du[x];
	else ans[x] = -du[x];
	for(auto it : v[x]){
		// debug(it);
		if(!ans[it]){
			dfs(it, u ^ 1);
		}
	}
} 
 
void solve()
{
	cin >> n;
	for(int i = 1; i <= n; i ++ ){
		du[i] = ans[i] = 0;
		v[i].clear();
	}
	for(int i = 1; i <= n - 1; i ++ ){
		int a, b;
		cin >> a >> b;
		du[a] ++;
		du[b] ++;
		v[a].pb(b), v[b].pb(a);
	}
	dfs(1, 1);
	for(int i = 1; i <= n; i ++ ){
		cout << ans[i] << ' ';
	}
	cout << endl;
}
 

标签:geq,Rated,frac,int,void,cin,Prizes,数组,Div
来源: https://www.cnblogs.com/acmerbs/p/16058541.html