HDU4639 HEHE
“hehe”这个词能代表两个意思‘hehe’或者‘wqnmlgb’,现在给出一个全由小写字母组成的句子,要求你计算这个句子到底表达了多少种意思。
输入:首先是一个T(1<=T<=100),然后以下T行,每行一个由小写字母组成的字符串(该串长度<=10086)。
输出:意思总数%10007的结果。
分析;
在没有hehe的句子里只能有1种意思。如果一个句子有很多段连续的hehehe或者hehe…he等,那么只要分别算每段he…he能表达多少种意思,然后求积求余即可。
现在用递推算出N(1<=N)个连续的he能表达的意思总数是S[N]:
S[0]=1,S[1]=1,S[2]=2,S[3]=3.假设hehehe…he串中从最右到最左转换为’WQNMLGB’的第一个hehe把长度为N的he…he串分成了长度为N1,和N2(N2串全由he…he组成)的串,且N1+N2=N-2。(未计算he…he串中没有一个hehe转换的情况,即保持所有字母都是原hehehehe等,该情况有1种)
3<=N时:S[N]=S[N-2]+S[N-3]+S[N-4]+…+S[1]+S[0]+1;(1表示不转换任何hehe的情况)
也可以这样分析:
最右边的那个he如果参与转变为‘WCNMLGB’则为S[N-2],否则为S[N-1]。
所以S[N]=S[N-2]+S[N-1];
#include<cstdio>
#include<cstring>
using namespace std;
const int MOD=10007;
int s[7000];
char str[10086+100];
int main()
{
s[0]=1;
s[1]=1;
s[2]=2;
s[3]=3;
for(int i=4; i<=7000; i++)
{
s[i]=1;
for(int j=i-2; j>=0; j--)
s[i]=(s[i]+s[j])%MOD;
}
int t;
scanf("%d",&t);
for(int k=1; k<=t; k++)
{
scanf("%s",str);
int sum=1,cur=0,len=strlen(str);
for(int i=0; i<len; i++)
{
if((i+1)<len&&str[i]=='h'&&str[i+1]=='e')
{
cur++;
i+=2;
while((i+1)<len&&str[i]=='h'&&str[i+1]=='e')
{
cur++;
i+=2;
}
//printf("cur is %d\n",cur);
sum=(sum*s[cur])%MOD;
cur=0;
}
}
printf("Case %d: %d\n",k,sum);
}
return 0;
}