P10131 Majority Opinion 题解
题意简述
给定一个长度为
分析样例
- 在
T=1 的情况下,2 连续出现了三次,此时可以选择区间[1,5] ,将所有位置替换为2 ,答案为2 。 - 在
T=2 的情况下,没有两个相邻位置是同样的数,所以无法替换,答案为-1 。 - 在
T=4 的情况下,出现了形如\{3,x,3\} 的情形,这时只需要选择这个长度为3 的区间替换为3 ,就可以转化为T=1 的情况了。
感性理解
- 当有两个相邻位置是同样的数时,可以将整个序列替换为这种数。
- 当有两个位置是同样的数,且中间只隔了一个位置,可以将整个序列替换为这种数。
- 当不存在上述两种情况时,无法替换。
严谨证明
结论一
假设
左方向操作方法:假设此时
右方向操作方法:假设此时
操作可行性:区间长度为
结论二
假设
替换后可以发现,
结论三
用反证法进行解决。如果上述两种情况都不存在,也就意味着任意连续的三个位置都互不相同。
假设存在可替换区间
赛时代码
注意特判行末空格即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 2e5 + 10;
ll T, n;
ll arr[N];
ll ok[N];
int main() {
cin >> T;
while (T--) {
memset(ok, 0, sizeof(ok));
cin >> n;
for (int i = 1; i <= n; i ++) {
cin >> arr[i];
if (arr[i] == arr[i - 1]) ok[arr[i]] = 1;
if (i > 1 && arr[i] == arr[i - 2]) ok[arr[i]] = 1;
}
ll cnt = 0;
for (int i = 1; i <= n; i ++) {
if (ok[i]) {
cnt ++;
}
}
if (cnt != 0) {
int cnt2 = 1;
for (int i = 1; i <= n; i ++) {
if (ok[i]) {
if (cnt2 != cnt) {
cnt2 ++;
cout << i << " ";
} else {
cout << i;
}
}
}
} else if (cnt == 0) cout << "-1";
cout << endl;
}
return 0;
}