CF544A Set of Strings 題解
阿新 • • 發佈:2021-12-21
CF544A Set of Strings 題解
、\(\texttt{re}\)、\(\texttt{i}\)、\(\texttt{s}\)、\(\texttt{awi}\)、\(\texttt{llthereisaway}\)。
Content
有一個長為 \(n\) 的字串 \(q\),試問能否將其劃分為 \(k\) 個子串,使得每個子串的首字母都不相等,可以的話輸出 \(\texttt{YES}\) 並輸出任意一個方案,否則輸出 \(\texttt{NO}\)。
資料範圍:\(1\leqslant n\leqslant 100,1\leqslant k\leqslant 26\)。
Solution
我們可以考慮這樣的一個流程:
- 輸入字串後,一個一個去掃。
- 如果有一個之前沒有出現過的字母,就立刻建立新的一個空子串。之後,將當前字元加入到當前子串裡面(有可能是之前已經有字母在裡面的子串,而不是新的子串)。
看不懂的話可以參照下面這個資料:
10
whenthereisawillthereisaway
下面是模擬過程——
- 從第一個字元 \(\texttt{w}\) 開始。
- 建立第一個空子串。將第一個字元加入到這個子串裡面,這時,第一個子串是 \(\texttt{w}\)。
- 掃到第二個字元 \(\texttt{h}\),前面沒有出現過,則建立第二個空子串,並將第二個字元加入到這個子串裡面,這時,第二個子串是 \(\texttt{h}\)。
- 掃到第三個字元 \(\texttt{e}\),前面沒有出現過,則建立第三個空子串,並將第三個字元加入到這個子串裡面,這時,第三個子串是 \(\texttt{e}\)。
- 掃到第四個字元 \(\texttt{n}\)
- 掃到第五個字元 \(\texttt{t}\),前面沒有出現過,則建立第五個空子串,並將第五個字元加入到這個子串裡面,這時,第五個子串是 \(\texttt{t}\)。
- 掃到第六個字元 \(\texttt{h}\),前面出現過,則將第六個字元加入到第五個子串裡面,這時,第五個子串是 \(\texttt{th}\)。
以此類推,這樣,最後的十個子串分別是 \(\texttt{w}\)、\(\texttt{h}\)、\(\texttt{e}\)、\(\texttt{n}\)、\(\texttt{the}\)
你也可以試試 \(k=17\) 的情況,此時應該輸出 \(\texttt{NO}\),具體請讀者自行模擬。
Code
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <iostream>
#include <cmath>
#include <map>
using namespace std;
int k, num;
string s, spre[107];
map<char, int> vis;
int main() {
scanf("%d", &k);
cin >> s;
num = 1;
spre[num] += s[0];
vis[s[0]] = 1;
for(int i = 1; i < s.size(); ++i) {
if(!vis[s[i]]) {
num++;
if(num > k) {
for(int j = i; j < s.size(); ++j)
spre[num - 1] += s[j];
break;
}
vis[s[i]] = 1;
}
spre[num] += s[i];
}
if(num < k) return printf("NO"), 0;
else {
puts("YES");
for(int i = 1; i <= num; ++i)
cout << spre[i] << endl;
}
}