牛客小白月赛3(18-5-12)---B-躲藏

B-躲藏

来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述
XHRlyb和她的小伙伴Cwbc在玩捉迷藏游戏。 Cwbc藏在多个不区分大小写的字符串中。 好奇的XHRlyb想知道,在每个字符串中Cwbc作为子序列分别出现了多少次。 由于Cwbc可能出现的次数过多,你只需要输出每个答案对2000120420010122取模后的结果。 聪明的你在仔细阅读题目后,一定可以顺利的解决这个问题!
输入描述:
输入数据有多行,每行有一个字符串。
输出描述:
输出数据应有多行,每行表示一个答案取模后的结果。

示例1

输入
Cwbc

输出
1

说明
Cwbc作为子序列仅出现了1次。

示例2

输入
acdcecfwgwhwibjbkblcmcnco

输出
81

说明
Cwbc作为子序列出现了3^4=81次。

备注:
每行字符串长度不超过2×10^5,字符串总长度不超过10^6。

解题思路
【1】简单DP思路
【2】先统计c出现的次数,由c出现的次数去更新w和c的可能搭配次数,再去更新b和 w 可能搭配的次数
【3】在统计c出现的次数时,有两种可能,一种是”cwbc”中第一个字符’c’,一种是第二个字符’c’

程序设计
1、方案一

#include<cstdio>
#include<iostream>
#include<cctype>
using namespace std;
//zhicheng
const long long maxn=2000120420010122;

int main()
{
    string ss;
//  freopen("1.txt","r",stdin);
    while(cin>>ss)
    {
        long long c=0,w=0,b=0,sum=0;
        for(int i=0;i<ss.length();i++)
        {
            ss[i]=tolower(ss[i]);
            switch(ss[i])
            {
                case 'c': c++;sum+=b;
                    if(sum>maxn) sum%=maxn;
                    break;
                case 'w': w+=c;break;
                case 'b': b+=w;break;
            }
        }
        printf("%lld\n",sum);
    }
    return 0;
}

Alt text
2、方案二
较方案一,仅仅只相对在空间上进行大幅度的优化,而代码中的差距仅是将switch功能改为if进行判断而已,可见switch在空间上的消耗高于if。

#include<cstdio>
#include<iostream>
#include<cctype>
using namespace std;
//zhicheng
const long long maxn=2000120420010122;

int main()
{
    string ss;
    //freopen("1.txt","r",stdin);
    while(cin>>ss)
    {
        long long f[4]={0};//分别为存放c、w、b出现的次数
        for(int i=0;i<ss.length();i++)
        {
            ss[i]=tolower(ss[i]);
            if(ss[i]=='c')
            {
                f[0]=(f[0]+1)%maxn;
                f[3]=(f[3]+f[2])%maxn;
            }
            if(ss[i]=='w')
                f[1]=(f[1]+f[0])%maxn;
            if(ss[i]=='b')
                f[2]=(f[2]+f[1])%maxn;
        }
        cout<<f[3]<<endl;
    }
    return 0;
}

Alt text

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值