NEUOJ 短信文字识别
题面
阿诚的胳膊被卡住了,拔不出来。不过身边有一台实体按键的手机,这样就可以盲打发短信来求救了(真庆幸不是触屏手机),但是这个手机发送的日文短信。即使看不见画面也应该能发邮件。
我认为朋友们很聪明,他们会给我正确的解释,但我现在发送的信息可能与我真正想发送的信息不同。这种手机字符输入方法与广泛使用的方法相同,例如,使用“1”按钮输入“あ”行的平假名字符。“1”代表“あ”,“11”代表“い”,以此类推,“11111”代表“お”。平假名是循环的,即“111111”也是“あ”。“か”行使用“2”,“さ”行使用“3”,…连续按下相同按钮的行为类似于“1”的例子。
但是,这个字符输入法有一个比较麻烦的行为。如果按下数字按钮后暂时不操作的话,就会被强制转换成平假名。也就是说,如果你连续按三次“1”,你就会得到“う”,但如果你每隔一段时间按三次“1”,你就会得到“あああ”。例如,当按下“111111”时,根据按下间隔时间的不同,输入的字符串可以是“あ”与可能是“ああああああ”。“111111111111”可能是“い”,可能是“ええいああ”,可能是“是”,也可能是12个“あ”。此外,当按下不同的数字按钮时,转换为平假名也会发生,因此“12345”很难被转换为字符串“あかさたな”。
好吧,我是小心翼翼地打的,所以我不认为我按错了按钮,但我不确定我能按到合适的时间间隔。很有可能发送了和真正想发送的信息不一样的东西。那么,可能发送了多少种字符串呢?
Input
输入由多个数据组成。
每个情况以以下格式给出。
string
输入的结尾由输入由“#”组成的行给出
字符串(string)最多包含100,000个介于0和9之间的数字。
字符串(string)长度大于10,000的输入不超过50个。
测试用例的文件大小保证为5 MB或更小。
此外,测试用例的数量不超过100个。
每个数字键可以输入的字符如下表所示。
数字输入对应的可能的文字
数字 | 可能的字符 | 可能字符数个数 |
1 | あいうえお | 5 |
2 | かきくけこ | 5 |
3 | さしすせそ | 5 |
4 | たちつてと | 5 |
5 | なにぬねの | 5 |
6 | はひふへほ | 5 |
7 | まみむめも | 5 |
8 | やゆよ | 3 |
9 | らりるれろ | 5 |
0 | わをん | 3 |
输出
字符串可能代表意思的数量,结果对100000007取模
输入样例
1
11
111111
111111111111
12345
11111111119999999999
11111111113333333333
11111111118888888888
11111111112222222222111111111
11111111110000000000444444444
11224111122411
888888888888999999999999888888888888999999999999999999
666666666666666777333333333338888888888
1111114444441111111444499999931111111222222222222888111111115555
#
输出样例
1
2
32
1856
1
230400
230400
156480
56217600
38181120
128
26681431
61684293
40046720
提示:
设f [i] 当有i个连续的1的方案数
对于f[i]来讲,将后k个1进行捆绑翻译为固定的汉字,显然当该行文字为5种时,最多从前5个转化过来。3种的从前三个转化过来。最后再加上一种把所有1识别为一个字的情况就好了
答案统计就是将连续的相同字符为一组然后相乘就好了
此题中的日文可简单理解为一种字符,例如以“1”代表‘a’,以“11”代表‘b’,那么“11”可能的结果有“aa”和“b”两种
1 1 1 1 1 1 1 | 1 f[i-1]
1 1 1 1 1 1 | 1 1 f[i-2]
1 1 1 1 1 | 1 1 1 f[i-3]
1 1 1 1 | 1 1 1 1 f[i-4]
1 1 1 | 1 1 1 1 1 f[i-5]
1 1 1 1 1 1 1 1 1 1
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <set>
#include <unordered_map>
#include <cstring>
#include <vector>
#include <map>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 1e6 + 100;
const int mod = 100000007;
typedef long long ll;
ll a5[N];
ll a3[N];
string s;
void ini() {
for (int i = 1; i <= 5; i++) {
a5[i] = pow(2, i - 1);
}
for (int i = 6; i <= 110000; i++) {
for (int j = 1; j <= 5; j++) {
a5[i] += a5[i - j];
a5[i] %= mod;
}
a5[i]++;
a5[i] %= mod;
}
for (int i = 1; i <= 3; i++) {
a3[i] = pow(2, i - 1);
}
for (int i = 4; i <= 110000; i++) {
for (int j = 1; j <= 3; j++) {
a3[i] += a3[i - j];
a3[i] %= mod;
}
a3[i]++;
a3[i] %= mod;
}
}
int cur = 0;
int len;
ll rdd() {
char c = s[cur];
int cnt = 0;
while (cur < len && s[cur] == c) {
cnt++;
cur++;
}
if (c == '8' || c == '0') {
return a3[cnt];
} else {
return a5[cnt];
}
}
int solve() {
cur = 0;
len = s.length();
ll ans = 1;
while (cur < len) {
ans *= rdd();
ans %= mod;
}
cout << ans % mod << endl;
}
int main() {
ini();
while (cin >> s) {
if (s == "#") break;
solve();
}
}