1705: 完美数组(New Online Judge)

1705: 完美数组(New Online Judge)

题目描述

完美数组的定义如下:
1、完美数组长度为偶数(包括0)
2、从左往右每两个数字都必须是一样的,即A、A、B、B、C、C…
例如:2 2 4 4 6 6 7 7是一个长度为8的完美数组。
现在,给你两个长度为n的数组,恰好每个数字出现2次,你可以删去一些数字,使得这两个数组变成完美数组。
删去数字时,无法改变其他数字的相对位置。
删去数字的代价为删去数字中的最大值。例如1 2 2 3 4 4删去数字1和3变成2 2 4 4,代价为3。
请问将这两个数组变成完美数组的最小代价是多少?

输入

输入第一行包含一个正整数n( 1 ≤ n ≤ 1 0 6 1≤n≤10^6 1n106)。
接下来两行每行n个数字,分别表示给定的两个数组。

输出

输出一个数字,表示最小代价。

样例输入

样例1:
5
2 1 3 3 2
6 6 7 1 7

样例2:
6
1 1 2 2 3 3
4 4 5 5 6 6

样例输出

样例1:
2

样例2:
0

题解1(C++版本)

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;

int n, a[N], ans;

bool check(int x){
	int last = -1;
	for(int i = 1; i <= n; i++){ //将所有<=x的元素都忽略掉 
		if(a[i] > x){
			if(last == -1) last = a[i];
			else if(last != a[i]) return false;
			else if(last == a[i]) last = -1;
		}
	}
	
	return last == -1 ?true : false; //最后一个值只有奇数个 
}

int main(){
	scanf("%d", &n);
	for(int k = 1; k <= 2; k++){
		memset(a, 0, sizeof a);
		int l = -1, r = 0, mid;
		for(int i = 1; i <= n; i++) scanf("%d", &a[i]), r = max(r, a[i]);
		r++;
		//l = -1, r= max(a[1],a[2],...,a[n])+1
		// 左边界的确定:不需要删除数组元素,此时代价为0
		// 右边界的确定:删除数组中的所有元素,此时代价为max(a[1],a[2],...,a[n])
		// 这里取开区间,方便处理边界
		while(l + 1 < r){ //二分答案
			mid = (l + r)/2;
			if(check(mid)) r = mid; //r最后一定指向这组数据的答案所在的位置
			else l = mid;
		}
		ans = max(ans, r);
	}
	printf("%d\n", ans);
	return 0;
}

  • 24
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值