BJTU1874 01数列

BJTU1874 01数列

题目:

有一个仅由0和1组成的数列,每次可以选择一对相邻的0和1消除。

求经过多次操作后,这个数列最短为多少?

输入数据:

一行一个长度为𝑛 (1≤𝑛≤105),仅包含 0 和 1的数列。

输出数据:

一行一个数字,表示经过多次操作后最短的数列长度。

样例:

输入1010011,输出1。

解释:

这道题大家一般先想到的都是贪心解决,每一次便利对相邻的两个元素进行判断,再对字符串进行删减。

所以我们先介绍这一种方法。

判断的条件当然就是相邻元素是否一个为0一个为1,此处我选择判断二者的和来判断(有多种方法),然后利用string类型的erase( )函数对字符串进行删改。

但是在这其中要注意字符串的下表也要随着其内容的删减而改变,例如删减了两个元素后,要遍历下一元素,则需要将 i-1 ,如果没有删减,才是 i++ ,这是比较关键的一点。

另外还有一点,尽量减少参数的传递,就算必须要用也尽量用引用解决,一开始就是吃了这个的亏吧可能,一直在函数里写的循环,然后在主函数调用,就一直TLE😭。最后写在了main函数中就AC了。

该种方法代码如下:

#include<cstdio>
#include<algorithm>
#include<string>
#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<vector>

using namespace std;

string s;

int main()
{
    cin>>s;
    int i = 0;

    while(i < s.size()-1 )
    {
        if ( s[i] + s[i + 1] == 0x61)
        {
            s.erase(i, 2);
            if(i > 0)
            {
                i -= 1;
            }
            if(s.size() < 2)
            {  
                break;
            }
        }
        else
        {
            i++;
        }
    }
    cout<<s.size()<<endl;
    return 0;
}

另外还有一种比较巧妙的解法,仔细思考一下,当这一串字符中有1且有0时,总会有一个1和一个0挨在一起,因此不必考虑字符01的位置关系,简单地通过数量关系就可以解决这个问题。

消去的元素个数,始终都是0,1中个数较小的数量的二倍。即:

min(num0,num1) * 2

因此最后的元素个数,用整体的size减去它即可,代码如下:

#include<cstdio>
#include<algorithm>
#include<string>
#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<vector>

using namespace std;

string s;

int main()
{
    int num1 = 0;
    int num0 = 0;
    cin>>s;
    
    for(int i = 0;i < s.length();i++)
    {
        if(s[i] == '0')
        {
            num0++;
        }
        else
        {
            num1++;
        }
    }
    cout<<s.length() - min(num0,num1)*2<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值