Codeforces Round #638 (Div. 2) A~C题解
Posted lasomisolaso~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #638 (Div. 2) A~C题解相关的知识,希望对你有一定的参考价值。
A
题意:
给出 2 1 , 2 2 , 2 3 , 2 4 , . . . 2 n 2^1,2^2,2^3,2^4,...2^n 21,22,23,24,...2n这n个数,n是偶数,将这n个数分成相等的两部分,问如何分配使这两部分的和之差最小,求出这个最小值。
题解:
我们知道 2 1 + 2 2 + 2 3 + . . . + 2 n − 1 < 2 n 2^1 + 2^2 + 2^3 + ... +2^n- 1 < 2^n 21+22+23+...+2n−1<2n,所以分配到 2 n 2^n 2n的一部分一定是两堆数中较大的一堆,我们要使这一堆数之和最小来缩短两堆的差距。所以将前 n / 2 − 1 n / 2 - 1 n/2−1个数分配给这堆即可。
B
题意:
一个数组是漂亮的,当且仅当它的任意一个长度为
k
k
k的子区间的和都为一个相同值的时候。给出我们一个数组,问是否能够向数组中插入若干个数字,使这个数组变成漂亮的。如果能输出最后的数组。无需最小化插入数字的数目。
题解:
我们不难发现,如果一个数组如果所有长度为k的子区间都为一个相同值的时候,那么这个数组就是以k为周期循环的。比如k = 4,数组为1 2 3 4 1 2 3 4 1 2 3。
因为这样从一个子区间走向下一个子区间的时候
s
u
m
−
a
[
l
]
+
a
[
l
+
k
]
sum - a[l] + a[l + k]
sum−a[l]+a[l+k]才能等于
s
u
m
sum
sum。
也就是说这个数组最多只能有
k
k
k个不同的数字。
我们通过统计给出的数组中的不同的数字,如果大于
k
k
k,那么肯定是不可以的。
如果小于等于
k
k
k,我们就把不同的数字都加入循环节,如果循环节长度不等于
k
k
k,可以随便补充数字。我们将循环节重复
n
n
n次,那么原数列的中每一个元素都对应一个循环节,也就是能通过插入数字的方式得到这个循环节。
能算出最后长度最长100 * 100小于等于10000。
代码:
/**
1. Author : Xiuchen
2. Date : 2020-05-01-23.59.04
3. Description : B.cpp
*/
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<cmath>
#include<math.h>
#include<iostream>
#include<algorithm>
//#define DEBUG
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3fLL;
const int maxn = 110;
int gcd(int a, int b)
return b ? gcd(b, a % b) : a;
int t;
int n, k, num[maxn], a[maxn];
vector<int> v;
int main()
#ifdef DEBUG
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
cin >> t;
while(t--)
cin >> n >> k;
v.clear();
memset(num, 0, sizeof(num));
for(int i = 1; i <= n; i++)
cin >> a[i];
if(num[a[i]] == 0) v.push_back(a[i]);
num[a[i]]++;
if(v.size() > k) cout << -1 << endl;
else
cout << k * n << endl;
for(int i = 1; i <= n; i++)
for(int j = 0; j < v.size(); j++) cout << v[j] << " ";
for(int j = 1; j <= k - v.size(); j++) cout << 1 << " ";
cout << endl;
return 0;
C.
题意:
给出一个字符串,分成
k
k
k个非空的字符串,问如何分配使这
k
k
k个字符串中的字典序最大的一个字符串字典序最小。给出字符串相当于给出了字符及其个数,分配的时候顺序可以打乱。详细见题目样例。
题解:
既然顺序是可以随便动的,只要个数不变就行。那么我们不妨将所有字符排个序。
首先这k个字符串的第一个字母都要尽量的小。所以把原字符串的排完序后的前k个字符依次分配给他们。
-
s
[
1
]
!
=
s
[
k
]
s[1] != s[k]
s[1]!=s[k],也就是说首个字母最后一个串分配的比第一个串分配的大。
这个时候我们可以直接就把后面所有的字符都分给第一个字符串,这不会改变最后一个字符串是最大字符串的事实,又保证了最后一个字符串尽可能地小。如第五个样例。 -
s
[
1
]
=
s
[
k
]
s[1] = s[k]
s[1]=s[k]
这个时候就不能妄下定论了。如果像上面一样做的话,第一个串就变成了最大串,这个最大串就不能保证尽可能小了。如第一组样例。
这个时候我们依然可以分两种情况。
第一种:后面所有的字符都相同。那最大的字符串一定是分配到个数最多的那个。我们将剩下的字符平均分到每个字符串就可以保证最大值最小化了。
第二种:后面的字符不相同。如样例2。我们假设第一个字符串是最大的。如果我们把后面的一些字符分配到第二个往后的字符串上。
要么会让第一个字符串不是最大的串,使后面的最大串大于原本把所有字符分配给第一个串的值。
要么就是第一个字符串依然是最大的串,但这个串的值依然是大于把所有字符分配给第一个串的值。
例如: 样例二,或者6 2 aabcde。大家手推一下就能发现。这种情况把所有剩余字符分配给第一个字符串是最优的。
这样的话所有的情况都覆盖。详细见代码。
/**
* Author : Xiuchen
* Date : 2020-05-02-00.26.19
* Description : C.cpp
*/
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<cmath>
#include<math.h>
#include<iostream>
#include<algorithm>
//#define DEBUG
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3fLL;
const int maxn = 1e5 + 100;
int gcd(int a, int b)
return b ? gcd(b, a % b) : a;
int t;
int k, n;
char s[maxn];
vector<char> v;
int main()
#ifdef DEBUG
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
cin >> t;
while(t--)
v.clear();
cin >> n >> k;
scanf("%s", s + 1);
sort(s + 1, s + n + 1);
if(s[1] != s[k]) cout << s[k] << endl;
else
v.push_back(s[1]);
if(n > k)
if(s[k + 1] != s[n])
for(int i = k + 1; i <= n; i++)
v.push_back(s[i]);
else
int num = ceil(1.0 * (n - k) / k);
for(int i = 1; i <= num; i++)
v.push_back(s[k + 1]);
for(int i = 0; i < v.size(); i++) cout << v[i];
cout << endl;
return 0;
以上是关于Codeforces Round #638 (Div. 2) A~C题解的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #638 (Div. 2)
Codeforces Round #638 (Div. 2)
Codeforces Round #638 (Div. 2)
Codeforces Round #638 (Div. 2)(A~B)
Codeforces Round #638 (Div. 2) A~C题解
CF A. Phoenix and Balance Codeforces Round #638 (Div. 2) 5月1号