Educational Codeforces Round 126 [Rated for Div. 2](A~C)

本文分享了三道编程竞赛题目及其解决方案。A题通过贪心策略,不断交换数组元素实现和的最小化;B题暴力枚举操作次数,找到使所有数变为0的最少数目;C题通过分类讨论,确定使所有树高度相同所需的最少数目。文章适合编程爱好者和竞赛选手阅读,提升算法思维和实战能力。

本人太弱了,只能够写三题。因为后一天要赶6点的班车,正赛就没打了,在导论课上补了三题(狗头) 接下来进入正题。

比赛链接:https://codeforces.com/contest/1661

A: Array Balancing

You are given two arrays of length nn: a1,a2,…,an and b1,b2,…,bn.

You can perform the following operation any number of times:

  1. Choose integer index i (1≤i≤n);
  2. Swap ai and bi.

What is the minimum possible sum |a1−a2|+|a2−a3|+⋯+|an−1−an||a1−a2|+|a2−a3|+⋯+|an−1−an| ++ |b1−b2|+|b2−b3|+⋯+|bn−1−bn||b1−b2|+|b2−b3|+⋯+|bn−1−bn| (in other words, ∑i=1n−1(|ai−ai+1|+|bi−bi+1|)∑i=1n−1(|ai−ai+1|+|bi−bi+1|)) you can achieve after performing several (possibly, zero) operations?

Input

The first line contains a single integer tt (1≤t≤40001≤t≤4000) — the number of test cases. Then, tt test cases follow.

The first line of each test case contains the single integer nn (2≤n≤252≤n≤25) — the length of arrays aa and bb.

The second line of each test case contains n integers a1,a2,…,an (1≤ai≤1e9) — the array a.

The third line of each test case contains n integers b1,b2,…,bn (1≤bi≤1e9) — the array b.

Output

For each test case, print one integer — the minimum possible sum ∑i=1n−1(|ai−ai+1|+|bi−bi+1|)∑i=1n−1(|ai−ai+1|+|bi−bi+1|).

题意大概是:给你两个数组,数组a和数组b,每次可以选取一个下标i,交换a[i]和b[i].问最终

| a[1]-a[2] |+| a[2]-a[3] |+...+| a[n]+a[n+1] |+ | b[1]-b[2] |+| b[2]-b[3] |+...+| b[n]+b[n+1] |的最小值

解析:其实题目就是一个贪心的过程(怎么说呢?迷迷糊糊就AC了),我们可以从1遍历到n,如果abs(a[i]-a[i+1])+abs(b[i]-b[i+1])>abs(b[i]-a[i+1])+abs(a[i]-b[i+1])  说明交换a[i+1]和b[i+1]的贡献会更小,所以进行交换。最后进行求和就完事了。

AC代码如下

#include<bits/stdc++.h>
using namespace std;
int a[35],b[35];
int main( ){
	int t,n;
	cin>>t;
	while(t--){
		cin>>n;
		for(int i=1;i<=n;++i){
			cin>>a[i];
		}
		for(int i=1;i<=n;++i){
			cin>>b[i];
		}
		for(int i=1;i<=n;++i){
			if(abs(a[i]-a[i+1])+abs(b[i]-b[i+1])>abs(b[i]-a[i+1])+abs(a[i]-b[i+1])){
				swap(a[i+1],b[i+1]);
			}
		}
		long long sum=0;
		for(int i=1;i<n;++i){
			sum+=abs(a[i]-a[i+1])+abs(b[i]-b[i+1]);
		}
		cout<<sum<<endl;
	}
	
} 

 

B. Getting Zero

Suppose you have an integer v. In one operation, you can:

  • either set v=(v+1)mod32768
  • or set v=(2⋅v)mod32768.

You are given nn integers a1,a2,…,an.What is the minimum number of operations you need to make each aiai equal to 0?

Input

The first line contains the single integer n (1≤n≤327681≤n≤32768) — the number of integers.

The second line contains nn integers a1,a2,…,an (0≤ai<327680).

题意大概是:给你n个数,通过这两种操作(第一种 v=(v+1)%32768,第二种(2*v)%32768) 把它变成0,问你最少操作数。

解析:当时写这题一点思路都没有。但其实通过本题不难发现,如果一直进行第二种操作把它变成0的话,最多也只要20多次的操作数。所以我们就可以快乐的暴力了。所以我们只要遍历第一种操作的个数,然后计算此时需要第二次操作的最小个数。最后取个最小值就行了哈。

#include<bits/stdc++.h>
using namespace std;
int Min;
int main( ) {
	int n,x;
	cin>>n;
	while(n--) {
		Min=1e9;
		cin>>x;
		int cnt=0;
		for(int j=0; j<=100; ++j) {
			int sum=x+j;
			sum=sum%32768;
			cnt=0;
			for(int i=1; i<=20; ++i) {
				if(sum==0) break;
				sum=sum*2;
				sum=sum%32768;
				cnt++;
			}
			Min=min(Min,cnt+j);
		}
		cout<<Min<<endl;
	}
}

C. Water the Trees

There are nn trees in a park, numbered from 1 to n. The initial height of the ii-th tree is hihi.

You want to water these trees, so they all grow to the same height.

The watering process goes as follows. You start watering trees at day 11. During the jj-th day you can:

  • Choose a tree and water it. If the day is odd (e.g. 1,3,5,7,…), then the height of the tree increases by 1. If the day is even (e.g. 2,4,6,8,…), then the height of the tree increases by 2.
  • Or skip a day without watering any tree.

Note that you can't water more than one tree in a day.

Your task is to determine the minimum number of days required to water the trees so they grow to the same height.

You have to answer tt independent test cases.

Input

The first line of the input contains one integer t(1≤t≤2⋅1e4) — the number of test cases.

The first line of the test case contains one integer n (1≤n≤3⋅1e5) — the number of trees.

The second line of the test case contains n integers h1,h2,…,hn(1≤hi≤1e9), where hi is the height of the i-th tree.

It is guaranteed that the sum of nn over all test cases does not exceed 3⋅1e5 (∑n≤3⋅1e5).

Output

For each test case, print one integer — the minimum number of days required to water the trees, so they grow to the same height.

题意大概是给你一个数组,在第i(i为奇数)次的操作中 你可以任选一个数进行加1,在i(i为偶数)次的操作中 你可以任选一个数进行加2.而且每次操作,你也可以选择跳过不做。问你要把数组中所有的数变成相等,最少要几次操作。

很多大佬选择二分求解,我也尝试过,但最终wa爆了。所以本蒟蒻选择了分类讨论了(TAT)。

解析:我们先找出这个数组的最大值Max,然后再求出其余的数达到这个Max,需要多少次偶数次操作和多少次奇数次操作。偶数次操作,我这里记为even,奇数次操作我记为odd。接下来就是愉快的分类讨论了。

1:当odd=even或者odd=even+1时候 答案为odd+even

2:当odd>even时候 答案为2*odd-1

3:当odd<even时候,我们就通过分配尽量把abs(odd-even)变小

      i:当(even-odd)刚好整除以3  odd变为odd + (even-odd) / 3 * 2,;

      even变为even-(even-odd)/3 答案为odd+even

      II : 当(even-odd)不整除时候,odd变为odd + (even-odd) / 3 * 2;

      even变为even-(even-odd)/3 此时又又要分两种讨论

            1:odd大于even 答案为odd+even;

             2:odd小于even 答案为odd+even+1;

讨论结束,但是陷阱就在这里。我们还要在进行一次操作,将Max变为Max+1(因为原数据求出来的even可能为0,从而无法达到操作最小值)。重复上述操作。再取最小值,别忘了开long long 哦

#include<bits/stdc++.h>
using namespace std;
long long a[300005];
int main( ) {
	int t,n;
	cin>>t;
	while(t--) {
		cin>>n;
		long long Max=0;
		for(int i=1; i<=n; ++i) {
			cin>>a[i];
			Max=max(Max,a[i]);
		}
		for(int i=1; i<=n; ++i) {
			a[i]=Max-a[i];
		}
		long long odd=0;
		long long even=0;
		for(int i=1; i<=n; ++i) {
			odd+=a[i]&1;
			even+=a[i]/2;
		}
		long long Min=1e18;
		if(odd==even||odd==even+1) Min=min(Min,odd+even);
		else if(odd<even) {
			if((even-odd)%3==0) {
				Min=min(Min,(odd+(even-odd)/3*2)*2);
			} else {
				if((odd+(even-odd)/3*2)>even-(even-odd)/3) {
					Min=min(Min,odd+(even-odd)/3*2+even-(even-odd)/3);
				} else {
					Min=min(Min,1+odd+(even-odd)/3*2+even-(even-odd)/3);
				}
			}
		} else {
			Min=min(Min,2*odd-1);
		}
		odd=0;
		even=0;
		for(int i=1; i<=n; ++i) {
			odd+=(a[i]+1)&1;
			even+=(a[i]+1)/2;
		}
		if(odd==even||odd==even+1) Min=min(Min,odd+even);
		else if(odd<even) {
			if((even-odd)%3==0) {
				Min=min(Min,(odd+(even-odd)/3*2)*2);
			} else {
				if((odd+(even-odd)/3*2)>even-(even-odd)/3) {
					Min=min(Min,odd+(even-odd)/3*2+even-(even-odd)/3);
				} else {
					Min=min(Min,1+odd+(even-odd)/3*2+even-(even-odd)/3);
				}
			}
		} else Min=min(Min,odd*2-1);
		cout<<Min<<endl;
	}
}

第一次发博客,确实有点粗糙。最后希望大家能够多多体谅。

"educational codeforces round 103 (rated for div. 2)"是一个Codeforces平台上的教育性比赛,专为2级选手设计评级。以下是有关该比赛的回答。 "educational codeforces round 103 (rated for div. 2)"是一场Codeforces平台上的教育性比赛。Codeforces一个为程序员提供竞赛评级的在线平台。这场比赛是专为2级选手设计的,这意味着它适合那些在算法数据结构方面已经积累了一定经验的选手参与。 与其他Codeforces比赛一样,这场比赛将由多个问题组成,选手需要根据给定的问题描述测试用例,编写程序来解决这些问题。比赛的时限通常有两到三个小时,选手需要在规定的时间内提交他们的解答。他们的程序将在Codeforces的在线评测系统上运行,并根据程序的正确性效率进行评分。 该比赛被称为"educational",意味着比赛的目的是教育性的,而不是针对专业的竞争性。这种教育性比赛为选手提供了一个学习提高他们编程技能的机会。即使选手没有在比赛中获得很高的排名,他们也可以从其他选手的解决方案中学习,并通过参与讨论获得更多的知识。 参加"educational codeforces round 103 (rated for div. 2)"对于2级选手来说是很有意义的。他们可以通过解决难度适中的问题来测试巩固他们的算法编程技巧。另外,这种比赛对于提高解决问题能力,锻炼思维提高团队合作能力也是非常有帮助的。 总的来说,"educational codeforces round 103 (rated for div. 2)"是一场为2级选手设计的教育性比赛,旨在提高他们的编程技能算法能力。参与这样的比赛可以为选手提供学习进步的机会,同时也促进了编程社区的交流与合作。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值