zzuli 20级第七次周赛 2739 问题 E: 无

题目描述

给一个序列a,包含n个整数,a的序号由1到n。你可以选择一个整数x(只能选一次,且x在序列a中),你可以进行一次或者多次下列操作:
你可以选择第r个到第l个连续的数字(1<=r<=l<=n),变成x,但有一个前提,第r到第l个数字中不能有等于x的数字。
求最少多少次操作,可以使整个序列a中的数都变成你所选的x。
例如n=6,a={1,3,2,4,1,2},你可以选择x=1,进行第一次操作,r=2,l=4,所以此时a={1,1,1,1,1,2}。再次进行操作,r=6,l=6,此时序列a={1,1,1,1,1,1}。

输入

输入第1行为一个整数t(1≤n≤10),代表测试的组数。
下面有t组测试数据每组有两行
第一行包括一个整数n,表示序列a有n个整数(1<=n<=200000)
第二行包括n个整数,a1,a2,a3,…,an (1<=ai<=n)

输出

输出最小的操作次数,使序列a中的整数全变为x

样例输入

5
3
1 1 1
5
1 2 3 4 5
5
1 2 3 2 1
7
1 2 3 1 2 3 1
11
2 2 1 2 3 2 1 2 3 1 2

样例输出

0
1
1
2
3

思路:求出每个数在数组中有几个区间,输出最小的即可。

#include <bits/stdc++.h>
using namespace std;

const int Maxn = 0x3f3f3f3f;

int arr1[200005];     //记录这个数是否出现过 
int arr2[200005];     //记录这个数上一次出现过的位置 
int arr3[200005];     //记录这个数的区间个数 
int main(){
	int t;
	cin >> t;
	while(t--){
		memset(arr1, 0, sizeof(arr1));
		memset(arr2, 0, sizeof(arr2));
		memset(arr3, 0, sizeof(arr3));
		
		int n, a;
		cin >> n;
		for(int i = 1; i <= n; i++){
			scanf("%d", &a);  
			if(i == n)		//特殊处理最后一个数。
				arr3[a]--;	
			//如果与这个数的上一次出现间隔大于1就代表中间隔得有区间 
			if(i - arr2[a] > 1)
				arr3[a]++;	
			//由于arr2初始值为0,所以第一个数直接被特殊处理了		
			arr1[a] = 1;				
			arr2[a] = i;
		}
		int ans = Maxn;
		for(int i = 1; i <= n; i++){
			if(arr1[i] == 1)
				ans = min(arr3[i], ans);
		}
		//1个数有2个区间,2个数有3个区间,所以要加1
		cout<< ans+1 <<endl;
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值