Codeforces 471 Div2 B 解题报告

题意:

给定一个字符串, 问它能否被分成两个子序列,使得这两个子序列均恰好含有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");
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值