题解:洛谷 P2852 [USACO06DEC] Milk Patterns G

【题目来源】

洛谷:[P2852 USACO06DEC] Milk Patterns G - 洛谷

【题目描述】

农夫约翰注意到他的奶牛所产的牛奶质量每天都在变化。经过进一步调查,他发现虽然无法预测牛奶质量从一天到下一天的变化,但每天的牛奶质量中存在一些规律模式。

为了进行严格的研究,他发明了一种复杂的分类方案,其中每个牛奶样本被记录为一个介于 \(0\)\(1,000,000\) 之间的整数,并记录了一头奶牛在 \(N\ (1 \le N \le 20,000)\) 天内的数据。他希望找到一个最长的样本模式,该模式至少重复 \(K\ (2 \le K \le N)\) 次。这可能包括重叠的模式——例如,1 2 3 2 3 2 3 1 中的 2 3 2 3 重复了两次。

帮助农夫约翰找到样本序列中最长的重复子序列。保证至少有一个子序列重复至少 \(K\) 次。

【输入】

\(1\) 行:两个用空格分隔的整数:\(N\)\(K\)

\(2\) 行到第 \(N+1\) 行:\(N\) 个整数,每行一个,第 \(i\) 行表示第 \(i\) 天的牛奶质量。

【输出】

\(1\) 行:一个整数,表示至少出现 \(K\) 次的最长模式的长度。

【输入样例】

8 2
1
2
3
2
3
2
3
1

【输出样例】

4

【算法标签】

《洛谷 P2852 Milk Patterns》 #二分# #哈希hashing# #后缀数组SA# #USACO# #2006#

【代码详解】

#include <bits/stdc++.h>
using namespace std;
const int N = 20005;

int n, k;
string s, a[N];
int sa[N];  // 前缀和数组,sa[i]表示前i个字符串拼接后的总字符数

// 检查是否存在长度为x的连续字符串组合出现至少k次
bool check(int x)
{
    // cout << "x " << x << endl;
    
    map<string, int> mp;
    for (int i = 1; i + x - 1 <= n; i++)
    {
        // 计算子串的起始和结束位置
        int st_pos = sa[i] - a[i].size() + 1;  // 第i个字符串的起始位置
        int ed_pos = sa[i + x - 1];            // 第(i+x-1)个字符串的结束位置
        // 提取子串
        string tmp = s.substr(st_pos, ed_pos - st_pos + 1);
        mp[tmp]++;  // 统计该子串出现的次数
    }
    int maxn = -1e9;
    for (auto t : mp)
    {
        maxn = max(maxn, t.second);  // 找到出现次数最多的子串
    }
    return maxn >= k;  // 判断是否有子串出现至少k次
}

int main()
{
    cin >> n >> k;
    s = " ";  // 在字符串前加一个空格,使索引从1开始
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        s += a[i];  // 将所有字符串拼接成一个长字符串
    }
    // 计算前缀和:sa[i]表示前i个字符串的总字符数
    for (int i = 1; i <= n; i++)
    {
        sa[i] = sa[i - 1] + a[i].size();
    }
    int l = 0, r = n;
    // 二分查找最大满足条件的x
    while (l < r)
    {
        int mid = (l + r + 1) / 2;
        if (check(mid))
        {
            l = mid;  // 满足条件,尝试更大的x
        }
        else
        {
            r = mid - 1;  // 不满足条件,减小x
        }
    }
    cout << l << endl;
    return 0;
}

【运行结果】

8 2
1
2
3
2
3
2
3
1
4
posted @ 2026-03-23 11:50  团爸讲算法  阅读(3)  评论(0)    收藏  举报