题目链接: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 ",r); return 0; }