1 条题解
-
0
题意分析
题目要求从多块损坏的机械手表中推断火山爆发的最可能时间区间。每块手表有三根外观相同的指针(时、分、秒),且表盘可任意旋转,导致时间解读不唯一。需考虑所有可能的指针排列和旋转角度,找到包含所有手表候选时间的最短区间。时间以12小时制表示,秒针每秒移动一格,分针每60秒移动一格,时针每12分钟移动一格。
解题思路
代码使用KMP算法处理时间匹配:1)预处理目标时间序列的next数组;2)对每个手表,枚举所有可能的指针排列和旋转角度,生成候选时间序列;3)动态维护当前时间序列的最长匹配前缀长度,当匹配到目标序列时回溯删除;4)最终输出剩余序列表示的最短时间区间。需注意:1)处理时间时需模12小时;2)输出格式要求严格;3)最短区间优先选择较早的开始时间。
#include<bits/stdc++.h> using namespace std; #define N 1000005 int nex[N], f[N]; char an[N]; void get_nex(char b[], int len) { nex[1] = nex[0] = 0; for (int i = 2, j = 0; i < len; i++) { while (j > 0 && b[i] != b[j + 1]) j = nex[j]; if (b[i] == b[j + 1]) j++; nex[i] = j; } } void solve(char a[], int lena, char b[], int lenb) { int ans = 0; //约定下标从1开始 for (int i = 1, j = 0; i <= lena; i++) { j = f[ans]; an[++ans] = a[i]; while (j > 0 && (j == lenb || an[ans] != b[j + 1])) j = nex[j]; if (an[ans] == b[j + 1]) j++; f[ans] = j; if (j == lenb) ans -= lenb; } for (int i = 1; i <= ans; i++) printf("%c", an[i]); } char a[N], b[N]; int main() { scanf("%s%s", a + 1, b + 1); int len = strlen(b + 1); get_nex(b, len); int len1 = strlen(a + 1); solve(a, len1, b, len); }
- 1
信息
- ID
- 2933
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者