题目描述
In the army, it isn't easy to form a group of soldiers that will be effective on the battlefield. The communication is crucial and thus no two soldiers should share a name (what would happen if they got an order that Bob is a scouter, if there are two Bobs?).
A group of soldiers is effective if and only if their names are different. For example, a group (John, Bob, Limak) would be effective, while groups (Gary, Bob, Gary) and (Alice, Alice) wouldn't.
You are a spy in the enemy's camp. You noticed n soldiers standing in a row, numbered 11 through n . The general wants to choose a group of k consecutive soldiers. For every k consecutive soldiers, the general wrote down whether they would be an effective group or not.
You managed to steal the general's notes, with n−k+1 strings ,each either "YES" or "NO". The string describes a group of soldiers 1 through k ("YES" if the group is effective, and "NO" otherwise).
Your task is to find possible names of n soldiers. Names should match the stolen notes. Each name should be a string that consists of between 11 and 1010 English letters, inclusive. The first letter should be uppercase, and all other letters should be lowercase. Names don't have to be existing names — it's allowed to print "Xyzzzdj" or "T" for example.
Find and print any solution. It can be proved that there always exists at least one solution.
输入格式
The first line of the input contains two integers n and k ( 2<=k<=n<=50 ) — the number of soldiers and the size of a group respectively.
The second line contains n−k+1 strings . The string si is "YES" if the group of soldiers i through i+k−1 is effective, and "NO" otherwise.
输出格式
Find any solution satisfying all given conditions. In one line print n space-separated strings, denoting possible names of soldiers in the order. The first letter of each name should be uppercase, while the other letters should be lowercase. Each name should contain English letters only and has length from 11 to 1010 .
If there are multiple valid solutions, print any of them.
Sample Input
8 3 NO NO YES YES YES NO
Sample Output
Adam Bob Bob Cpqepqwer Limak Adam Bob Adam
题意翻译:
现有 n 个名字,需要满足 n−k+1 个要求。
对于每个要求有 "YES" 或 "NO" 两种情况。
YES 表示的是从第 i 个名字到第 i+k−1 个名字都不相同。
NO 表示第 i 个名字到第 i+k−1 个名字至少有两个相同的名字。
要求你构造出符合条件的 n 个名字。
名字自取,要求首字母大写,其余小写。
这道题的题干非常的长啊,总之我们需要操控一个字符串数组,使其满足YES和NO要求的相同不同情况,很容易会有两种想法。
第一是先让所有的名字相同,然后根据题目中的YES,再把YES的区间里面的名字赋值成各不相同。我一开始是这么想的,但是后来发现不能这么简单,因为区间里的相同名字有要求,如果区间重叠,相同的名字要跟不同的区间中的名字某一个相同。所以这种思路不是特别好处理。
第二种思路就是先令所有的名字不同,再根据题目中的NO,把NO的区间里制造出2个相同的名字。那么根据贪心的思想,肯定对于每个NO的区间,我们只改造成有2个名字相同恰好满足的条件。选哪两个名字改造?可以试试区间的头尾,因为区间的头尾是不容易对其他区间造成影响的。于是我们可以将区间的右端赋值为区间的左端,那么对于下一个区间来说,左端右移一格,我们制造的那个相同的前一个左端就不会下一个YES区间造成影响。于是就可以这么做。
接下来还要处理的一个事情就是题目要求的符合条件的名字的构造。这里因为数据量比较小,所以我直接手动for循环26个字母去赋值,后来补题时看到题解里别人采用一个巧妙的办法,就是把十进制转26进制字母表示,然后再把首字母操作一下变成大写。就可以直接for循环里制造符合的名字了,这个转换过程我写在外面封装成函数zhuan(int i),具体的代码如下:
#include<bits/stdc++.h>
#include<unordered_map>
#define ll long long
#define pii pair<int,int>
using namespace std;
const int maxn = 2e5 + 10;
string str[101];
int flag[101];
ll read() {
ll x = 0, f = 0, ch = getchar();
while (!isdigit(ch)) { if (ch == '-')f = 1;ch = getchar(); }
while (isdigit(ch)) { x = x * 10 + ch - '0';ch = getchar(); }
return f ? -x : x;
}
string zhuan(int i) {
string res = "";
while (i) {
res += i % 26 + 'a';
i /= 26;
}
res[0]=res[0] - 'a' + 'A';
return res;
}
int main() {
ll a = read(), b = read();
for (int i = 0;i < a - b + 1;i++) {
string tem;
cin >> tem;
if (tem == "NO") {
flag[i] = 1;
}
}
string name[51];
for (int i = 1;i < 51;i++)
name[i] = zhuan(i);
for (int i = 0;i < a;i++) {
str[i] = name[i+1];
}
for (int i = 0;i < a-b+1;i++) {
if (flag[i]) {
str[i + b - 1]=str[i];
}
}
for (int i = 0;i < a;i++)
cout << str[i] << " ";
return 0;
}