1 条题解
-
0
题目回顾
我们需要模拟一个二进制女巫的天气预测方法。给定一个长度为的二进制字符串(表示雨天,表示晴天),预测接下来的天的天气。预测规则如下:
- 对于第天的预测,从最后位开始(),逐步减少的值(),检查当前序列的最后位是否在之前出现过。
- 如果找到匹配的后缀,则预测值为该匹配位置后一位的值(即)。
- 如果有多个匹配,选择最靠右的(即最大的)。
- 如果没有找到匹配,则预测为雨天()。
- 对于后续的预测(第天到第天),将之前的预测结果添加到序列末尾,并重复上述过程。
解题思路
为了高效实现上述规则,可以采用以下方法:
- 预处理:使用一个二维数组,其中表示后缀长度(到),是一个位的二进制数的十进制表示。存储的是该最后一次出现的起始位置。
- 动态更新:在遍历序列时,动态更新,记录每个可能的位后缀的最后出现位置。
- 预测:
- 对于第天(从到),检查最后到位的所有可能后缀,找到最大的使得后缀在之前出现过。
- 根据匹配的后缀位置,确定预测值(即匹配位置后一位的值)。
- 如果没有匹配,预测为。
- 将预测值添加到序列末尾,并继续更新。
代码实现
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN = 1111111; int d[14][1<<14]; // d[t][mask] stores the last occurrence of the t-length suffix represented by mask char str[MAXN]; int main() { int n, l; while(~scanf("%d%d", &n, &l)) ```cpp #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN = 1111111; int d[14][1<<14]; char str[MAXN]; int main() { int n,l; while(~scanf("%d%d",&n,&l)) { scanf("%s",str+1); memset(d,-1,sizeof(d)); for(int i = 1;i<=n+l;i++) { if(i >= n) { int pos = -1; int tmp = 0; for(int j = 1;j<=13;j++) { if(i - j + 1 <= 0) break; tmp = (tmp<<1) + str[i - j + 1] - '0'; if(d[j][tmp] != -1) { pos = d[j][tmp]; } } if(pos != -1) { str[i+1] = str[pos+1]; } else str[i+1] = '0'; //printf("i = %d,pos = %d\n",i,pos); } int tmp = 0; for(int j = 1;j<=13;j++) { if(i - j + 1 <= 0) break; tmp = (tmp << 1) + str[i - j + 1] - '0'; d[j][tmp] = i; } } for(int i = 1;i<=l;i++) printf("%c",str[n+i]); puts(""); } return 0; }
- 1
信息
- ID
- 1542
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 4
- 已通过
- 1
- 上传者