题意:
给定一个字符串, 问它能否被分成两个子序列,使得这两个子序列均恰好含有2种不同的字母
思路:
咳咳,水题啊,标准水题 ~ 我们acm集训队的一位大佬最开始开map写T了......Emmm......说实话由于我很辣鸡不太会用map,所以我选择疯狂特判 ~ 就是根据题意,分成两部分,每一部分有且只有两个不同字母,所以首先,字母种数必须介于2 ~ 4之间,一种或者四种以上都没法满足题意,然后串长必须大于4,不然still没法满足题意,然后就剩三种情况了:
有两种字母:每种字母最少有两个就ok了,举个栗子~aaab,显然挫掉, abab, 显然满足
有三种字母:只要有一种字母超过一个就可以了, 再举个例子,abc,显然挫掉,abbc,显然满足
有四种字母:永远不挫,只要有四种,分分钟满足题意
代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL;
const int Maxx = 1e5 + 7;
char s[Maxx];
bool vis[Maxx];
int main() {
while(~scanf("%s", s)) {
memset(vis, 0, sizeof(vis));
int len = strlen(s);
int cnt = 0;
if(len < 4) {
puts("No");
continue;
}
for(int i = 0; i < len; i++) {
if(!vis[s[i]]) {
vis[s[i]] = 1;
cnt++;
}
}
if(cnt > 4 || cnt == 1) {
puts("No");
continue;
}
//printf("%d\n", cnt);
if(cnt == 2) {
int c1 = 0, c2 = 0;
for(int i = 0; i < len; i++) {
if(s[i] == s[0]) c1++;
else c2++;
}
if(c1 >= 2 && c2 >= 2) puts("Yes");
else puts("No");
}
else if(cnt == 3) {
int a1 = 0, a2 = 0, a3 = 0;
int tmp;
for(int i = 0; i < len; i++) {
if(s[i] == s[0]) a1++;
else tmp = s[i];
}
for(int i = 0; i < len; i++) {
if(s[i] == tmp) a2++;
else if(s[i] != tmp && s[i] != s[0]) a3++;
}
//printf("%d %d %d\n", a1, a2, a3);
if(a1 + a2 + a3 >= 4) puts("Yes");
else puts("No");
}
else if(cnt == 4) puts("Yes");
}
}