Educational Codeforces Round 107 (Rated for Div. 2) D. Min Cost String(构造)

题意:

构造一个长度为 n n n字符串,只能使用字母表前 k k k 个字母,使得 s i = s j s_i=s_j si=sj 并且 s i + 1 = s j + 1 s_{i+1} =s_{j+1} si+1=sj+1 ( i , j ) (i,j) (i,j) 数量最少。

题解:

n n n到达一定长度时,必然会存在上述 ( i , j ) (i,j) (i,j)

那么我们先考虑如何利用这 k k k个字母先构造出一个最长的字符串,满足不存在上述 ( i , j ) (i,j) (i,j)

其实,每个字母后面最多有 k k k种情况,。比如 k = 4 k=4 k=4, 那么 a a a 就是 a a , a b , a c , a d aa ,ab ,ac ,ad aa,ab,ac,ad

将这四种合起来,大致可以分为两种构造情况:

1. 1. 1. a a b a c a d aabacad aabacad

2. 2. 2. a b a c a d a a abacadaa abacadaa

那么选择哪一种呢?显然要第一种,因为第二种后面不管放什么都会出现相等,而第一种后面还能再去构造 b b b

即: a a b a c a d b b c b d aabacadbbcbd aabacadbbcbd ,构造 b b b的时候就不能再把 a a a放进来,以此类推。最后就可以构造出 k ⋅ k k \cdot k kk 的字符串,也就是每个字母都被使用了 k k k次,保证了最长。

最后要构造长度为 n n n 的字符串,那么就以这个 k ⋅ k k \cdot k kk 的字符串为循环节即可。

代码:

#pragma GCC diagnostic error "-std=c++11"
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<stack>
#include<set>
#include<ctime>
#define iss ios::sync_with_stdio(false)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int,int> pii;
const int mod=1e9+7;
const int MAXN=2e5+5;
const int inf=0x3f3f3f3f;
int main() {
    
    int n, k;
    cin >> n >> k;
    string s;
    for(int i = 0; i < k; i++)
    {
        s += 'a' + i;
        for(int j = i + 1; j < k; j++)
        {
            s += 'a' + i;
            s += 'a' + j;
        }
    }
    for(int i = 0; i < n; i += 1) cout << s[i % s.size()];
    return 0;
}
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 像素格子 设计师:CSDN官方博客 返回首页