【Codeforces】Pinely Round 1 (Div. 1 + Div. 2) B. Elimination of a Ring | 签到

154 阅读2分钟

本文已参与「新人创作礼」活动, 一起开启掘金创作之路。

题目链接

Problem - B - Codeforces

题目

image.png

题目大意

将大小为 nn 的循环序列定义为长度为 nn 的数组 ss,其中 sns_ns1s_1 相邻。

给定大小为 nn 的循环序列 aa 表示的环。如果序列中的两个相邻元素在任何时候相等,其中一个元素将立即被删除。序列最初不包含相等的相邻元素。

Muxii 可以执行以下操作,直到序列变为空:

  • 选择一个元素并将其删除。

例如,如果环为 [1,2,4,2,3,2][1,2,4,2,3,2],并且 Muxii 选择元素 44 进行操作,则环将变成 [1,2,2,3,2][1,2,2,3,2]。此时出现了两个相邻的相等元素,于是等于 22 的元素之一将会消失,并且环将变为[1,3,2,2]。

Muxii 想找到他可以执行的最大操作数。

请注意,在大小为 1 的环中,其唯一元素不被视为与自身相邻(因此不会立即删除)。

思路

简单题……赛中没考虑清楚随便猜了一发结论喜提 FST,于是写了题解。

容易发现,对于仅包括两种元素的环,我们每进行一次操作一定会使得两个相同元素碰到一起,直到序列中只剩下两个元素。所以我们可以进行的操作次数是 n/2+1n/2+1(该情况下 nn 一定是偶数)。

包括两种以上元素的环,我们总可以通过以下策略执行 nn 次操作:
环中必然存在一个位置 ii,满足 ai1ai+1a_{i-1}\neq a_{i+1}。此时如果环中还有等于 aia_i 的位置,我们就删除 aia_i,环中数字的种类数不会改变。环中不存在其他等于 aia_i 的位置时,我们可以一直删除 aia_i 旁边的元素,直到只剩下 aia_i

代码

#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;
}