版本1
先把没坏的键标记。如果是标记坏掉的键可能出现前面的字符满足坏键,后面的字符不满足坏键的性质。
#include <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
#include <cstring>
#include <set>
#include <string>
#include <algorithm>
using namespace std;
//散列
int main()
{
int k;
cin >> k;
int mp[256]={0}; //统计每个字符出现的次数 在遍历中改变
int sure[256]={0};
string str;
cin >> str;
//用数组来标记可能坏掉的键 1表示可能坏 0是默认 2是没坏
for (auto c : str)
mp[c]++;
for (int i = 0; i < str.size();)
{
if (mp[str[i]] % k == 0)
{
bool flag = false;
int j;
for (j = 0; j < k; j++)
{
if (i + j == str.size() || str[j + i] != str[i])
{
flag = true;
break;
}
}
if (!flag) //可能坏了
{
mp[str[i]] -= k;
}
else{ //肯定没坏
sure[str[i]] = 2;
mp[str[i]] -= j;
}
i += j;
}
else
{
sure[str[i]] = 2;
mp[str[i]]--;
i++;
}
}
set<char> st;
for(auto c: str) {
if(sure[c] != 2){
if(!st.count(c)){
cout<<c;
st.insert(c);
}
}
}
cout<<endl;
for(int i = 0; i < str.size(); ){
if(st.count(str[i])) {
cout<<str[i];
i+=k;
}else{
cout<<str[i];
i++;
}
}
return 0;
}