A:
思路:
我们先构造出最大长度codeforce div2 659 A-C题解:_ios字符串codeforce div2 659 A-C题解:_i++_02,然后遍历数组codeforce div2 659 A-C题解:_i++_03,缩小codeforce div2 659 A-C题解:_i++_02字符串长度与codeforce div2 659 A-C题解:_i++_05的大小相同,然后codeforce div2 659 A-C题解:_#include_06之间我们随意填充即可,但随意填充的字符codeforce div2 659 A-C题解:_i++_07
参考代码:

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <ctime>
#include <cstring>
#include <cstdlib>
#include <math.h>
using namespace std;
typedef long long ll;
const int N = 1e3 + 5;
const ll maxn = 1e5 + 5;
int a[maxn];
char s[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while (t--)
{
memset(s, 0, sizeof s);
int n;
cin >> n;
int len = 0;
for (int i = 0; i < n; i++)
cin >> a[i], len = max(len, a[i]);
len++;
for (int i = 1; i <= len; i++)
s[i] = 'a';
cout << s + 1 << endl;
for (int i = 0; i < n; i++)
{
int j = len;
for (j; j > a[i]; j--)
;
for (j = j + 1; j <= len; j++)
{
char c = 'a';
while (c == s[j])
{
c = rand() % 26 + 'a';
}
s[j] = c;
}
cout << s + 1 << endl;
}
}
}

B:
思路:
如果我们在codeforce div2 659 A-C题解:_#include_08个海域可以待上codeforce div2 659 A-C题解:_ios_09秒,呢么说明我们可以平安到岸
首先我们直接排除最坏的可能 codeforce div2 659 A-C题解:_ios_10 这肯定是不可能的
呢么我们就看,每个海滩我们最多能待多少秒codeforce div2 659 A-C题解:_i++_11秒,如果当前海域我们能一直待下去,呢么当然就可以平安到岸了,如果待不下去就往前去,然后贪心即可

参考代码:

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <ctime>
#include <cstring>
#include <cstdlib>
#include <math.h>
using namespace std;
typedef long long ll;
const int N = 1e3 + 5;
const ll maxn = 3e5 + 5;
int a[maxn];
char s[N];
map<int, int> mp;
int pre[maxn], sum[maxn];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while (t--)
{
int n, k, l;
cin >> n >> k >> l;
bool fla = true;
for (int i = 0; i < n; i++)
cin >> a[i];
int now = -k;
for (int i = 0; i < n; i++)
{
int d = l - a[i];
if (d < 0)
{
fla = false;
break;
}
if (d >= k)
now = -k;
else
now = max(now + 1, -d);
if (now > d)
{
fla = false;
break;
}
}
if (fla)
cout << "Yes" << endl;
else
cout << "No" << endl;

}
}

C:
这个题我们可以发现,对于一块的集合我们操作集合数量-1次即可,也就是说用图来表示的话,字符串上下位置进行连通,呢么我们每次对一个集合进行操作即可,呢么操作次数不就想让小的变成大的,然后再变,最终不就操作集合数量-1次,呢么答案累加所有连通块的操作次数即可,连通块只出现一次,但查找的时候会出现很多次,但根节点只有一个,所以只对根节点操作即可
参考代码:

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <ctime>
#include <cstring>
#include <cstdlib>
#include <math.h>
using namespace std;
typedef long long ll;
const int N = 1e3 + 5;
const ll maxn = 1e5 + 5;
int a[maxn];
char s[N];
map<int, int> mp;
int pre[maxn], sum[maxn];
int f(int x)
{
if (x != pre[x])
pre[x] = f(pre[x]);
return pre[x];
}
void join(int x, int y)
{
x = f(x), y = f(y);
if (x != y)
sum[y] += sum[x], pre[x] = y;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while (t--)
{
for (int i = 0; i <= 20; i++)
pre[i] = i, sum[i] = 1;
int n;
string s1, s2;
cin >> n;
cin >> s1;
cin >> s2;
int ans = 0;
for (int i = 0; i < n; i++)
{
if (s2[i] - s1[i] < 0)
{
ans = -1;
break;
}
int x = s1[i] - 'a' + 1, y = s2[i] - 'a' + 1;
if (f(x) != f(y))
join(x, y);
}
if (ans == -1)
{
cout << -1 << endl;
continue;
}
for (int i = 0; i < 21; i++)
if (i == f(i))
ans += sum[f(i)] - 1, sum[f(i)] = 0;
cout << ans << endl;
}
}