** Codeforces Round #665 (Div. 2)A-D题解**
//写于rating值2075/2184
//下午刚补的题,28号之前都要练科三,这段时间的比赛应该都要鸽了
比赛链接:https://codeforces.com/contest/1401
A题
简单思维
题意为在x轴上有一个点A位于(n,0),现在给定一个值k,你需要找到一个点B位于(m,0)满足m<=n,使得原点(0,0)到B的距离与A到B的距离的差的绝对值等于k。(n,m,k均为整数)
如果无法找到这样的点,我们可以对点A进行任意次操作,每次操作我们可以使n的值增大或减小1。
现在需要你输出最小的操作次数,使得我们可以找到满足要求的点B。
首先当n=k的情况下,我们可以选择B点为(0,0),这样的情况下OB长度为0,AB长度为n=k,两段距离差值为k满足要求,需要操作次数为0。
如果n 如果n>k的话,此时并不是说必定不需要操作的。还需考虑n和k的奇偶性。假设OB长度为L1,AB长度为L2,且L1>L2,由于n,m,k都必须是整数,因此L1和L2的长度也为整数。 B题 现在有两个数列只包含0,1,2,两个数列长度相等。 现在你需要对这两个数列的数字两两配对, 现在需要你输出最终答案可能的最大值。 这道题每个数列中只有0,1,2三种数字,且存在0,最后的计算又是乘法。我们直接讨论下9种情况很容易发现, 而正增加和负增加的两种选择是不冲突的,我们直接贪心选取最多对数的正增加和最少对数的负增加即可。 我们能增加的最多对数的x=2,y=1,为第一个数列中2的个数和第二个数列中1的个数的最小值。 C题 给定一个长度为n的数列,其中最小的数字为Min,你每次可以选择这个数列中两个下标不同的数字x和y满足gcd(x,y)=Min,交换这两个数字的位置。 首先要认识到一点,原数列中,数值无法整除Min的,代表其因子中根本不含有Min,那么它与其他数字的gcd必定不为Min,因此它的位置是不可改变的。 那么原数列中 ,排除掉无法整数Min的数,剩下的那些可以整除Min的数字,我们又可以通过题意给定的操作把它们排序到什么程度呢? 也就是说,数值无法整除Min的数字们,我们是无法改变它们的位置的,而可以整除Min的数字们,我们是可以将他们按照从小到大排序好的。 由此我们直接对原数列排序,注意数值相等的时候要按照下标从小到大排序,因为无法整除Min的数字可能数值相等,而他们的位置是不可改变的,也就是原数列中的先后顺序应当被保留。因此我们不可以直接使用不稳定的快速排序。检测一下无法整除Min的数字,它们排序后所在的位置下标是否都与原位置下标相同,如果不同则代表无法构造。 D题 给定一棵树有n个结点,n-1条边。现在需要你对每条边给定一个数值,这n-1条边对应的数值相乘需要等于给定的数字k。由于k可能会非常庞大,题目输入数据为k分解质因子后的结果。 现在需要使得累加所有任意两点间的简单路径的边的数值和,这个最后的结果要尽可能大,且对每条边构造数值的时候,1的数量要尽可能的少。 我们首先需要想到的,对于这棵树上的每条边,他在最后的结果中被累加了多少次呢。 我们可以通过一遍从根节点出发的dfs计算出每个节点的子节点数,并由此计算出每条边在最后的结果中被计算了多少次。 之后是对这n-1条边如何构造数值的过程了。
已知L1+L2=n,L1-L2=k,得L1=L2+k
得2 × \times × L2=n-k,也就是说n-k必须是偶数。
因此当n-k不为整数时,我们还需要对n进行一次+1的操作。#include
分类,贪心,简单思维
第一个数列有a1个0,b1个1,c1个2。
第二个数列有a2个0,b2个1,c2个2。
设第一个数列中选出的数字为x,第二个数列中选出的数字为y
当x=y时,累加0到答案上
当x>y时,累加x × \times × y到答案上
当x
只有当x=2,y=1的时候,会对最终答案有正增加,
只有当x=1,y=2的时候,会对最终答案有负增加,
其他情况对答案的增加都是0。
在这之后我们希望x=1,y=2的对数尽可能少,那么我们让第二个数列中的2尽可能先与第二个数列中的0和2配对,剩下的只能与1配对,这种情况下即为最少配对数。#include
排序,整体思维
现在询问你是否可以通过任意次上述操作后,使得数列变为从小到大排序的数列。
数列中必然有一个数字是等于Min的,Min与任何一个可以整除它的数字的gcd必然等于Min,也就是说Min这个数字是可以与任意其他剩下的数字交换位置的。
一旦有一个数字满足了上述的可以与任意其他位置的数字交换位置,我们就可以通过这个数字进行类似插入排序的过程,把整个数列都排序完毕。#include
贪心,简单图结论
以题目的第一个样例的图为例:
在上图中,中间的这条边,左侧有两个点1和2,右侧有两个点3和4。这条边总共被计算了2 × \times × 2=4次。也就是左侧的节点个数乘以右侧的节点个数,因为左侧的点到右侧的点的简单路径必然要经过当前这条边。而左侧的点走到左侧点或是右侧的点走到右侧的点的简单路径,是不需要经过当前边的。
题目要求这n-1条边的数值乘积要等于k,那么必然的他们分解质因数的结果要与k相同。
当k分解质因数得到的质因子个数m<=n-1的时候,我们直接采用贪心的过程,按照质因子个数大的与边在最后结果中出现次数的进行两两配对即可。m#include