[week15] 苟狗之宇宙射线再打击

题意

苟狗定义了一种新式字符串,只有掌握了这种字符串的构造方法,才可以避免宇宙射线的打击。

新式字符串定义如下:

1.长度为偶数(可以为空)
2.每一个奇数位置的字符都不等于它后面的那个字符
例如,字符串 good、string、xyyx 都符合要求,而字符串 bad、aa、aabc 则不符合。

现在你获得了一个字符串 S,你需要从该字符串中删除最少的字符数,使其变成一个新式字符串,否则你就会受到宇宙射线的打击,众所周知宇宙射线是降智射线。

那么你能够避开宇宙射线吗?

Input

一个行给定一个整数 N(1 <= N <= 200000),表示字符串 S 的长度。

第二行给定长度为 N 且仅包含小写字母的字符串 S。

Output

第一行输出一个数 K(0 <= K <= N),表示需要从 S 中删除的最少的字符数量。

第二行输出删除后的字符串 S。如果为空,你可以输出一个空字符串或者什么都不输出。

输入样例

4
good


4
aabc


3
aaa

输出样例

0
good


2
ab


3

提示


分析


  • 题目分析

这道题不难,但是同样的可能也是有点不好理解。至少我是没有理解到的👋

这道题其实需要将原字符串复制到新字符串中,但是在复制过程中进行筛选,使得新字符串一定满足题目要求。

题目要求,

  • 字符串长度为偶数
  • 字符串中的奇数位置字符与后一个字符不等

注意此处的要求是针对新复制的字符串,因此奇数位置指的是在新字符串中的位置,而不是选定字符在原字符串中是否是奇数位置。而偶数长度指的也是新字符串,而不是原字符串的长度。

因此,解决方法是:

  • 遍历原字符串,记录当前新字符串中待加入字符的位置。
  • 若当前遍历字符要加入在新字符串中的偶数位置,则说明对该字符无任何要求,因此可以直接加入
  • 若加入在新字符串的奇数位置,则需要判断:若该字符在原字符串中的下一个字符和它不一样,则说明这个字符可以直接加入(因为下一个字符一定是加入到新字符串的偶数位置,所以这个字符一定会被添加,因此在新字符串中这两个字符不能相等);反之,则这个字符不能被加入到新字符串的当前奇数位置。

总结

  1. 确实不大懂,而且其实不大明白为什么这样就保证减少的字符数最少

代码

//
//  main.cpp
//  lab5
//
//

#include <string>
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;

vector<char> output;

int main()
{
    ios::sync_with_stdio(false);
    
    int n = 0;
    string s;
    
    cin>>n>>s;
    
    int j = 1;      //当前字符在新字符串中的位置序号
    
    for( int i = 0 ; i < n - 1 ; i++ )      //遍历原字符串中除最后一个字符外的所有字符
    {
//        cout<<i<<" i "<<j<<" j "<<s[i]<<endl;
        if( j % 2 == 0 )            //如果当前字符在新字符中是偶数位置,则可以直接放入(没有限制)
        {
            output.push_back(s[i]);
            j++;                    //新字符位置序号+1
        }
        else                        //若在新字符串中是奇数个,则需要判定
        {
            //因为它的在原字符串的下一个一定会被放入到新字符串中,因此当前字符一定不能和下一个字符相等
            if( s[i] != s[i + 1] )
            {
                output.push_back(s[i]);     //不相等则可以放入
                j++;
            }
        }
    }
    
    //若所得新字符串是奇数个,则最后一个必须放入,否则可以不用放入
    //若所得是奇数个,则在之前最后放入的那个字符一定已经判定过和其后一个字符不同,所以最后一个字符可以直接放入
    //否则的话到此为止只有偶数个
    if( output.size() % 2 != 0 )
        output.push_back(s[n - 1]);
    
    
    cout<<n - output.size()<<endl;      //字符串长度差即为去掉字符个数
    for( int i = 0 ; i < output.size() ; i++ )      //输出
        cout<<output[i];
    cout<<endl;
    
    
    
    
    
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天翊藉君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值