(CF 638 (Div2))
(A.)
给定 (n) 个数,分别为 (2^1, 2^2, ..., 2^n),保证 (n) 是偶数,是否可以将这些数分成两组,使得两组之间数字和的差最小,输出这个差值
注意到 (2^1 + 2^2 +.. + 2^{n - 1} = 2^n - 1)
如果一组拿到 (2^n),那么另一组必须拿 (2^{n - 1}, 2^{n - 2}, ..., 2^{frac{n}{2}})
等比数列求和一下
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int, int>
#define pb push_back
#define arrayDebug(a, l, r) for(int i = l; i <= r; ++i) printf("%d%c", a[i], "
"[i == r])
typedef long long LL;
typedef unsigned long long ULL;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int DX[] = {0, -1, 0, 1, 0, -1, -1, 1, 1};
const int DY[] = {0, 0, 1, 0, -1, -1, 1, 1, -1};
const int MOD = 1e9 + 7;
const int N = 2e5 + 7;
const double PI = acos(-1);
const double EPS = 1e-6;
using namespace std;
inline int read()
{
char c = getchar();
int ans = 0, f = 1;
while(!isdigit(c)) {if(c == '-') f = -1; c = getchar();}
while(isdigit(c)) {ans = ans * 10 + c - '0'; c = getchar();}
return ans * f;
}
int t, n;
int main()
{
t = read();
while(t--) {
n = read();
int k = n / 2;
printf("%lld
", (1LL << (k + 1)) - 2);
}
return 0;
}
(B.)
给定长度为 (n) 的序列 (a),其中 (1leq a_{i}leq n)
可以在任意位置插入 (1sim n) 范围内的数字(包括首尾)
要求新数组中任意长为 (k) 的子数组的和都一样,输出这个新数组
其中,(1leq kleq nleq 100)
如果一个数组任意长为 (k) 的子数组和都一样,那么它必然有长度为 (k) 的循环节
考虑构造这个循环节
将序列 (a) 中数字去重,若去重后的数量大于 (k),则无法构造长度为 (k) 的循环节;反之可以(长度不够的话填充 (1sim n) 内的任意整数)
最暴力的构造方式即为,输出 (n) 个循环节,新数组长度为 (n imes k)
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int, int>
#define pb push_back
#define arrayDebug(a, l, r) for(int i = l; i <= r; ++i) printf("%d%c", a[i], "
"[i == r])
typedef long long LL;
typedef unsigned long long ULL;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int DX[] = {0, -1, 0, 1, 0, -1, -1, 1, 1};
const int DY[] = {0, 0, 1, 0, -1, -1, 1, 1, -1};
const int MOD = 1e9 + 7;
const int N = 2e5 + 7;
const double PI = acos(-1);
const double EPS = 1e-6;
using namespace std;
inline int read()
{
char c = getchar();
int ans = 0, f = 1;
while(!isdigit(c)) {if(c == '-') f = -1; c = getchar();}
while(isdigit(c)) {ans = ans * 10 + c - '0'; c = getchar();}
return ans * f;
}
int t, n, k;
int main()
{
t = read();
while(t--) {
n = read(), k = read();
set<int> st;
for(int i = 1; i <= n; ++i) {
int x = read();
st.insert(x);
}
if(st.size() > k) puts("-1");
else {
vector<int> sub;
for(auto i: st) sub.pb(i);
for(int i = 1; i <= k - int(st.size()); ++i) sub.pb(1);
printf("%d
", n * k);
for(int i = 1; i <= n; ++i) {
for(int j = 0; j < k; ++j)
printf("%d%c", sub[j], "
"[i == n && j== k - 1]);
}
}
}
return 0;
}
/*
*/
(C.)
给定一个字符串 (s),要求分配每一个字符,将 (s) 划分成 (k) 个新串 (s_{i}),且每个字符都只分配一次,同时最小化新串中字典序最大的串,即 (minimize left{s_{i}mid i = 1, 2, ..., k ight}),输出这个串
将 (s) 升序排序,记共有 (kind) 个不同字符
考虑平均分配前 (k) 个字符,
-
若 (s[k - 1] eq s[0]),那么 (ans = s[k - 1]),例如
[s = aabbb, k = 3 Rightarrow s_{1} = abb, s_{2} = a, s_{3} = b ] -
若 (s[k - 1] = s[0]),考虑后缀 (s[k - 1: n])
-
若 (kind = 1),平均分配即可,例如
[s = aaaaaaa, k = 3 Rightarrow s_{1} = aa, s_{2} = aa, s_{3} = aaa ] -
若 (kind = 2)
- 若 (s[k - 1] = s[k]),直接输出后缀,例如[s = aaabbb, k = 2 Rightarrow s_{1} = a, s_{2} = aabbb ]
- 若 (s[k - 1]
eq s[k]),平均分配,例如[s = aabbb, k = 2 Rightarrow s_{1} = ab, s_{2} = abb ]
- 若 (s[k - 1] = s[k]),直接输出后缀,例如
-
若 (kind > 2),直接输出后缀,例如
$$
s = aabbc, k = 2 Rightarrow s_{1} = a, s_{2} = abbc
$$
-
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int, int>
#define pb push_back
#define arrayDebug(a, l, r) for(int i = l; i <= r; ++i) printf("%d%c", a[i], "
"[i == r])
typedef long long LL;
typedef unsigned long long ULL;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int DX[] = {0, -1, 0, 1, 0, -1, -1, 1, 1};
const int DY[] = {0, 0, 1, 0, -1, -1, 1, 1, -1};
const int MOD = 1e9 + 7;
const int N = 2e5 + 7;
const double PI = acos(-1);
const double EPS = 1e-6;
using namespace std;
inline int read()
{
char c = getchar();
int ans = 0, f = 1;
while(!isdigit(c)) {if(c == '-') f = -1; c = getchar();}
while(isdigit(c)) {ans = ans * 10 + c - '0'; c = getchar();}
return ans * f;
}
int t, n, k;
string s;
int main()
{
t = read();
while(t--) {
n = read(), k = read();
cin >> s;
sort(s.begin(), s.end());
if(s[k - 1] != s[0]) cout<<s[k - 1]<<endl;
else {
set<int> st(s.begin(), s.end());
if(st.size() == 1) {
int len = s.length() % k ? s.length() / k + 1 : s.length() / k;
//cout<<len<<endl;
for(int i = 1; i <= len; ++i) putchar(s[0]);
puts("");
}
else if(st.size() == 2) {
if(k < n - 1 && s[k - 1] == s[k]) {cout<<s.substr(k - 1, s.length() - k + 1)<<endl;}
else {
int len = s.length() % k ? s.length() / k + 1 : s.length() / k;
putchar(s[k - 1]);
if(k < n) for(int i = 1; i < len; ++i) putchar(s[k]);
puts("");
}
}
else cout<<s.substr(k - 1, s.length() - k + 1)<<endl;
}
}
return 0;
}
/*
6
4 2
baba
5 2
baacb
5 3
baacb
5 3
aaaaa
6 4
aaxxzz
7 1
phoenix
*/