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;
}
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;
}