本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
题目链接
题目
题目大意
将大小为 的循环序列定义为长度为 的数组 ,其中 与 相邻。
给定大小为 的循环序列 表示的环。如果序列中的两个相邻元素在任何时候相等,其中一个元素将立即被删除。序列最初不包含相等的相邻元素。
Muxii 可以执行以下操作,直到序列变为空:
- 选择一个元素并将其删除。
例如,如果环为 ,并且 Muxii 选择元素 进行操作,则环将变成 。此时出现了两个相邻的相等元素,于是等于 的元素之一将会消失,并且环将变为[1,3,2,2]。
Muxii 想找到他可以执行的最大操作数。
请注意,在大小为 1 的环中,其唯一元素不被视为与自身相邻(因此不会立即删除)。
思路
简单题……赛中没考虑清楚随便猜了一发结论喜提 FST,于是写了题解。
容易发现,对于仅包括两种元素的环,我们每进行一次操作一定会使得两个相同元素碰到一起,直到序列中只剩下两个元素。所以我们可以进行的操作次数是 (该情况下 一定是偶数)。
包括两种以上元素的环,我们总可以通过以下策略执行 次操作:
环中必然存在一个位置 ,满足 。此时如果环中还有等于 的位置,我们就删除 ,环中数字的种类数不会改变。环中不存在其他等于 的位置时,我们可以一直删除 旁边的元素,直到只剩下 。
代码
#include <iostream>
#include <algorithm>
#include <math.h>
#include <stdio.h>
#include <map>
#include <vector>
#include <queue>
#define nnn printf("No\n")
#define yyy printf("Yes\n")
using namespace std;
using LL=long long;
const int N=500001;
const LL mod=1000000007;
int n,m,k,x,y,z,tot,a[N],v[N];
LL solve()
{
for (int i=1;i<=n;++i) v[a[i]]=0;
scanf("%d",&n);
for (int i=1;i<=n;++i) scanf("%d",&a[i]);
m=0;
for (int i=1;i<=n;++i)
{
if (v[a[i]]==0) m++;
v[a[i]]=1;
}
if (m==2) printf("%d\n",n/2+1);
else printf("%d\n",n);
return 0;
}
int main()
{
int T=1;
scanf("%d",&T);
while (T--) solve();
// solve();
return 0;
}