A Phoenix and Balance
由于\(\sum_{i=1}^{n-1}2^i=2^n-2\),为了使重量差最小,将最重的与最轻的\(\frac{n}{2}-1\)个放在一起,因此答案为\((2^n+\sum_{i=1}^{\frac{n}{2}-1}2^i)-\sum_{i=\frac{n}{2}}^{n-1}2^i=2^{\frac{n}{2}+1}-2\)
#include <bits/stdc++.h>
using namespace std;
#define debug(x) cout << #x << " is " << x << endl
#define inc(i, a, b) for (int i = a; i <= b; ++i)
typedef long long ll;
const int INF = 2e9;
int t, n;
int bit[20];
int main()
{
scanf("%d", &t);
bit[0] = 1;
for (int i = 1; i <= 16; ++i) bit[i] = bit[i-1]<<1;
while (t--) {
scanf("%d", &n);
printf("%d\n", bit[n/2+1]-2);
}
return 0;
}
B Phoenix and Beauty
漂亮数组以\(k\)为周期,那么如果原数组有超过\(k\)个不同的数,则无解,否则,将原数组每个数扩展至\(k\)个即可。
#include <bits/stdc++.h>
using namespace std;
#define debug(x) cout << #x << " is " << x << endl
#define inc(i, a, b) for (int i = a; i <= b; ++i)
typedef long long ll;
const int INF = 2e9;
int t, n, k;
set<int> s;
int main()
{
scanf("%d", &t);
while (t--) {
scanf("%d%d", &n, &k);
s.clear();
int x;
for (int i = 1; i <= n; ++i) { scanf("%d", &x); s.insert(x); }
if ((int)s.size() > k) { puts("-1"); continue; }
printf("%d\n", n * k);
for (int i = 1; i <= n; ++i) {
for (int it : s) printf("%d ", it);
for (int j = 1; j <= k - (int)s.size(); ++j) printf("%d ", 1);
}
puts("");
}
return 0;
}
C Phoenix and Distribution
贪心,对字符串排序,要使分配的\(k\)个字符串中的字典序最大值最小,第一个字符必为第\(k\)小,如果最小的不与其相等,可将剩余字符全部分配至最小字符后。否则,如果最大字符不与第\(k\)小相等,则将第\(k\)小后面字符分配至其后,反正则平均分配后面字符。
#include <bits/stdc++.h>
using namespace std;
#define debug(x) cout << #x << " is " << x << endl
#define inc(i, a, b) for (int i = a; i <= b; ++i)
typedef long long ll;
const int INF = 2e9;
int t, n, k;
string s;
int main()
{
cin >> t;
while (t--) {
cin >> n >> k;
cin >> s;
sort(s.begin(), s.end());
if (s[0] != s[k-1]) { cout << s[k-1] << '\n'; continue; }
cout << s[k-1];
if (s[k] != s[n-1]) {
for (int i = k; i < n; ++i) cout << s[i];
}
else {
for (int i = 0; i < (n - 1) / k; ++i) cout << s[n-1];
}
puts("");
}
return 0;
}
D Phoenix and Science
贪心,问题可转化为\(\{a_n\}\)满足\(a_0=1\),使得\(a_i\leq a_{i+1}\leq2a_i\)且\(\sum_{i=1}^{len}a_i=n\),要使\(len\)最小化,构造\(1,2,\cdots,2^k\)使得其和\(s\)小于或等于\(n\),若小于\(sum\),插入\(n-sum\)并排序即得一个满足题意的最短序列。
#include <bits/stdc++.h>
using namespace std;
#define debug(x) cout << #x << " is " << x << endl
#define inc(i, a, b) for (int i = a; i <= b; ++i)
typedef long long ll;
const int INF = 2e9;
int t, n;
int main()
{
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
vector<int> v;
for (int i = 1; i <= n; i <<= 1) {
v.push_back(i);
n -= i;
}
if (n) {
v.push_back(n);
sort(v.begin(), v.end());
}
printf("%d\n", (int)v.size() - 1);
for (int i = 1; i < (int)v.size(); ++i) printf("%d ", v[i] - v[i-1]);
puts("");
}
return 0;
}
E Phoenix and Berries
F