题目链接:https://vjudge.net/problem/CodeForces-1290A#author=zzuli_practice
题目大意:每个人都能做一个操作,拿走数列中的第一个数或者第二个数,你可以指定k个人拿走的数,你是第m
个人,问你能拿到的最小的数最大是多少?
这题的思路有点像尺取(类似于游标卡尺的操作吧,不过这回游标的固定长度的).首先可以明确的是,轮到第m次选的时候
你可以选这个数列的第一个数,也可以选最后一个,因为m-1是固定的,所以剩下的数列个数也是固定的,我们把这个剩下的
数列称为"游标", 那么他的移动范围呢?如果我们指定k个人都取最后面的,那么他的最左端就是第一个数, 如果我们指定k个人
都取最前面的,那么他的最左端就是k+1个数, 所以他的移动范围就是1-k+1, 那么我们假设前k个数选好了,要求剩下的人随机选的情况
下选出的最小的数的最大值怎么办呢?其实我们可以再弄一个"游标", 因为前面已经选过k个数了,那么剩下随机选的个数(不算自己)就是m-k-1个
以第一个游标的位置为0位置,那么第二游标的最左端的范围就是0~m-k-1,然后在最优策略下,选出的数就是第二游标左右端点的最大值,最后我们只要求
这些最大值之中的最小值就行了
#include<set> #include<map> #include<list> #include<stack> #include<queue> #include<cmath> #include<cstdio> #include<cctype> #include<string> #include<vector> #include<climits> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define endl '\n' #define rtl rt<<1 #define rtr rt<<1|1 #define lson rt<<1, l, mid #define rson rt<<1|1, mid+1, r #define maxx(a, b) (a > b ? a : b) #define minn(a, b) (a < b ? a : b) #define zero(a) memset(a, 0, sizeof(a)) #define INF(a) memset(a, 0x3f, sizeof(a)) #define IOS ios::sync_with_stdio(false) #define _test printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n") using namespace std; typedef long long ll; typedef pair<int, int> P; typedef pair<ll, ll> P2; const double pi = acos(-1.0); const double eps = 1e-7; const ll MOD = 1000000007LL; const int INF = 0x3f3f3f3f; const int _NAN = -0x3f3f3f3f; const double EULC = 0.5772156649015328; const int NIL = -1; template<typename T> void read(T &x){ x = 0;char ch = getchar();ll f = 1; while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();} while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f; } const int maxn = 1e4+10; int arr[maxn]; int main(void) { int t; scanf("%d", &t); while(t--) { zero(arr); int m, n, k; scanf("%d%d%d", &n, &m, &k); for (int i = 0; i<n; ++i) scanf("%d", &arr[i]); int ans = -1; if (k>=m) k = m-1; //最理想情况下我们只要m前面的数都可以指定就可以 for (int i = 0; i<=k; ++i) { int temp = INF; for (int z = 0; z<=m-k-1; ++z) temp = min(temp, max(arr[z+i], arr[z+i+n-m])); //第二游标的区间长度就是选掉m个数之后的长度+1即n-m+1 ans = max(ans, temp); //因为下标从0开始了就是n-m了 } printf("%d\n", ans); } return 0; }