fjnu2019级第一次欢乐友谊赛D题 题解

D - 是

Codeforces Round #597 (Div. 2) C. Constanze's Machine

Constanze is the smartest girl in her village but she has bad eyesight.
One day, she was able to invent an incredible machine! When you pronounce letters, the machine will inscribe them onto a piece of paper. For example, if you pronounce ‘c’, ‘o’, ‘d’, and ‘e’ in that order, then the machine will inscribe “code” onto the paper. Thanks to this machine, she can finally write messages without using her glasses.
However, her dumb friend Akko decided to play a prank on her. Akko tinkered with the machine so that if you pronounce ‘w’, it will inscribe “uu” instead of “w”, and if you pronounce ‘m’, it will inscribe “nn” instead of “m”! Since Constanze had bad eyesight, she was not able to realize what Akko did.
The rest of the letters behave the same as before: if you pronounce any letter besides ‘w’ and ‘m’, the machine will just inscribe it onto a piece of paper.
The next day, I received a letter in my mailbox. I can’t understand it so I think it’s either just some gibberish from Akko, or Constanze made it using her machine. But since I know what Akko did, I can just list down all possible strings that Constanze’s machine would have turned into the message I got and see if anything makes sense.
But I need to know how much paper I will need, and that’s why I’m asking you for help. Tell me the number of strings that Constanze’s machine would’ve turned into the message I got.
But since this number can be quite large, tell me instead its remainder when divided by 109+7
If there are no strings that Constanze’s machine would’ve turned into the message I got, then print 00.

Input

Input consists of a single line containing a string ss (1≤|s|≤105) — the received message. ss contains only lowercase Latin letters.

Output

Print a single integer — the number of strings that Constanze’s machine would’ve turned into the message ss, modulo 109+7.

Examples
Input

ouuokarinn

Output

4

Input

banana

Output

1

Input

nnn

Output

3

Input

amanda

Output

0

Note

For the first example, the candidate strings are the following: “ouuokarinn”, “ouuokarim”, “owokarim”, and “owokarinn”.
For the second example, there is only one: “banana”.
For the third example, the candidate strings are the following: “nm”, “mn” and “nnn”.
For the last example, there are no candidate strings that the machine can turn into “amanda”, since the machine won’t inscribe ‘m’.

题意

某某发明了一台机器,当你念字母时,机器会把它们写在一张纸上。她的朋友某某恶作剧改动了机器,机器会将“m”写成“nn”,将“w”写成“uu”。
给定一个被改动的字符串,输出原串可能的种类数。如果原串不存在,输出0。

思路

萌新被群主迫害写题解,有错误请指出。
因为其它字符都不改动,只寻找连续的字符u或n,算出所有连续的字符“u”或“n”的原串种数,然后相乘即可。
以n为例,设连续k个字符n的原串种数为 f (k) 。当只有1个n时,原串也只有1种,即“n”,所以 f (1) = 1;当有2个n时,原串有2种,即“nn”或“m”,所以 f (2) = 2;当有k个n时 (k > 2),原串有 f (k) 种,讨论两种情况
1最后一个n在原串中也是n时,原串种数等于前 k - 1 个n的原串种数即 f (k - 1)
2最后一个n和倒数第二个在原串中是m时,原串种数等于前 k - 2 个n的原串种数即 f (k - 2) 。
由此得出递推公式 f (k) = f(k - 1) + f(k - 2),会发现这是斐波那契数列。
然后打表记 f (k),可以降低时间复杂度,数据较大,记得每步取模。

代码

//#define TEST
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxn 100005
#define MOD 1000000007

char str[maxn], last;
long long total = 1;
int l, k, f[maxn];

int main(){
	f[1] = 1;
	f[2] = 2;
	for(int i = 3; i <= maxn - 5; i++){
		f[i] = f[i - 1] + f[i - 2];
		f[i] = f[i] % MOD;
	}

	scanf("%s", str);
	l = strlen(str);
	k = 0;
	last = '0';
	for(int i = 0; i < l; i++){
		if(str[i] == 'w' || str[i] == 'm'){
			total = 0;
			break;
		}
  
		if(last == str[i])
			k++;
   
		if((last == 'u' || last == 'n') && str[i] != last){
			total = (total * f[k]) % MOD;
			k = 0;
			last = '0';
		}
  
		if(last == '0' && (str[i] == 'u' || str[i] == 'n')){
			last = str[i];
			k++;
		}
   
		if(i == l - 1 && k)
			total = (total * f[k]) % MOD;

#ifdef TEST
		cout << last <<' '<< k <<' '<< total << endl;
#endif

	}
	cout << total << endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值