CF 764 div3
CF 764 div3
没想到div3能打成这熊样子,确实是自己太菜了。D题调了半天,重构好几次……
A
这题没的说最大值减最小值
B
判断能否修改一个数使这三个数是等差数列。
一共三种情况,枚举修改哪一个数,根据等差数列性质这个数是可以算出来的。之后简单判断一下能不能满足修改条件。
C
这题没想到是贪心,但我也不知道为什么贪心是对的。
题意
给n个数,每个数都可以进行不限量的 /2 操作,问这n个数能否在操作后形成1-n的全排列。
sov
策略是从小到大排序,依次判断这个数能够满足的最大的数。核心代码如下:
sort(a + 1, a + n + 1);
memset(v, 0, sizeof(v));
for(register int i = 1; i <= n; ++i)
{
while(a[i])
{
if(a[i] <= n && !v[a[i]])
{
v[a[i]] = true;
break;
}
a[i] >>= 1;
}
}
ans = 1;
for(register int i = 1; i <= n; ++i)
{
ans = ans & v[i];
}
D
这题真够细节。
题意
给一个字符串染k种色,可以有剩下的字符不染但k种颜色必须全部使用。并且使每种颜色的字符都能够组成回文数。求最长的最短回文字符串。
翻译一下就是找k个回文字符串并且最大化最短的那个。
sov
策略:每次找一对扔给当前最短的,最后考虑把剩的奇数个字符分给每一个字符串。
计算上可以进行简化,统计一共有多少个偶数对字符,把他们平均分给k个字符串,多的就当成奇数字符使用。
//统计偶数对字符个数和奇数个字符个数
for(register int i = 0; i + 'a' <= 'z'; ++i)
{
cct += (cnt[i] / 2) * 2, odd += cnt[i] & 1;
}
//平均分偶数的
int ans = cct / k;
//多余的偶数个字符给奇数
odd += cct % k;
//如果当前答案是偶数,还能塞进去一个奇数字符
//判断可供使用的奇数字符够不够,够了就++ans
if(ans % 2 == 0 && odd >= k)
++ans;