cf1370D---二分+思维

题目链接:https://codeforces.com/contest/1370/problem/D

题意:长度为n的序列a中选出长度为k的子序列s,求min(max(s1,s3,s5...),max(s2,s4,s6...))

考虑二分答案,看对于二分的m,能不能构造出长度至少为k的子序列。注意题目中的式子,只要s中奇数位的值全部<=m,或者偶数位的值全部<=m即可。因此可以对奇数位和偶数位分别验证,验证的时候注意跳跃取数即可(比如验证的是奇数位,跳跃取数可以保证偶数位可以插入)。

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

const int maxn=2e5+10;
int t,n,i,j,k,l,r,m,n1;
int a[maxn];

bool check(int x){
	int len;
	i=1;len=0;
	if (k%2==0) n1=n-1;else n1=n;
	while (i<=n1){
	  if (a[i]<=x){len++;i+=2; }
	  else i++;
	}
	if (k%2==0&&len>=k/2) return true;
	if (k%2==1&&len>=k/2+1) return true;
	i=2;len=0;
	if (k%2==0) n1=n;else n1=n-1;
	while (i<=n1){
	  if (a[i]<=x){len++;i+=2; }
	  else i++;
	}
	if (len>=k/2) return true;
	return false;
}

int main(){
	scanf("%d%d",&n,&k);
	for (i=1;i<=n;i++) scanf("%d",&a[i]);
	l=0;r=1e9;
	while (r-l>1){
	  m=(l+r)/2;
	  if (check(m)) r=m;else l=m;
	}
	printf("%d\n",r);
	return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/edmunds/p/13398381.html