题面
You are given an array of integers . You are allowed to perform the following operation once.
- Select an integer (which may be negative), and for each value , set .
For example, if , and you perform the operation with , is now equal to .
Output the maximum possible value of after the operation is performed.
^{\text{∗}}$$\operatorname{MEX}(a) is defined as the smallest non-negative integer that is not present in the array. For example, is , and is .
Input
The first line of the input contains a single integer () — the number of test cases.
The first line of each test case contains a single integer () — the length of array .
The second line contains integers () — the array .
It is guaranteed that the sum of over all test cases does not exceed .
Output
For each test case, output the maximum possible value of after the operation has been performed.
思路
理清题意:
本题允许把所有元素同时加上同一个整数 ,因此数组中元素之间的相对差值不变
设操作后数组为 ,若希望 ,则 必须都在 中出现
把条件换回原数组可得, 中必须包含: 这一段长度为 的连续整数
反过来若 中存在连续段 ,选择 就能把它整体平移成 ,从而保证
因此最大可得的 恰好等于原数组去重后最长连续整数段的长度
因此,我们先对数组排序并去重,因为 只关心某个值是否出现过,重复元素不会带来额外贡献
线性扫描去重后的有序数组,用 表示当前连续段长度,用 表示历史最大值
当相邻两个数满足 时令 增加 ,否则将 重置为 ,并持续更新
最终输出 即为答案
代码
#include <bits/stdc++.h>
using namespace std;
int main() { int t; cin >> t; while (t --) { int n; cin >> n; vector<long long> a(n); for (int i = 0; i < n; i ++) cin >> a[i];
sort(a.begin(), a.end()); a.erase(unique(a.begin(), a.end()), a.end());
int best = 0; int cur = 0; for (size_t i = 0; i < a.size(); i ++) { if (i == 0 || a[i] != a[i - 1] + 1) cur = 1; else cur ++; best = max(best, cur); }
cout << best << endl; } return 0;}