codeforce div2 659 A-C题解:

A:
思路:
我们先构造出最大长度 L L 字符串 S S ,然后遍历数组 a [ i ] a[ i] ,缩小 S S 字符串长度与 a [ i ] a[i ] 的大小相同,然后 a [ i ] L a[ i]-L 之间我们随意填充即可,但随意填充的字符 c ! = S [ a [ i ] + 1 ] c!=S[a[i]+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];
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:
思路:
如果我们在 n n 个海域可以待上 k k 秒,呢么说明我们可以平安到岸
首先我们直接排除最坏的可能 a [ i ] l < 0 a[i]-l<0 这肯定是不可能的
呢么我们就看,每个海滩我们最多能待多少秒 [ 1 > k ] [1->k] 秒,如果当前海域我们能一直待下去,呢么当然就可以平安到岸了,如果待不下去就往前去,然后贪心即可

参考代码:

#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;
    }
}

猜你喜欢

转载自blog.csdn.net/yangzijiangac/article/details/107586841