• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

RomanLin

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

【滑动窗口】codeforces 1290 A. Mind Control

题意

第一行输入一个正整数 \(T(1 \leq T \leq 1000)\),表示共有 \(T\) 组测试用例。对于每一组测试用例:
第一行输入三个正整数 \(n, m, k(1 \leq m \leq n \leq 3500, 0 \leq k \leq n - 1)\),且保证 \(n\) 之和不超过 \(3500\),第二行输入 \(n\) 个整数 \(a_i(1 \leq a_i \leq 10^9)\)。

总的有 \(n\) 个整数,每次会从两端任意取走其中一个数。你可以任意控制 \(k\) 次取数的方案,比如第 \(j\) 次取数可以控制取的数是当前剩余的数里最前面的一个。你要做的是找出一个 \(X\),使得无论如何取数,都能使得第 \(m\) 次取数不小于 \(X\)。输出 \(X\)。

题解

若控制第 \(j(j > m)\) 的取数方案,因为第 \(m\) 个数已经取过,显然对结果不会影响,因此只需要控制前 \(w = min(m - 1, k)\) 个数的取数方案。
不妨暴力枚举删除前 \(left\) 个数和后 \(right\) 个数,其中 \(0 \leq left, right = w - left \leq w\) 的情况下,在接下来的第 \((m - w)\) 次取数时能取到的数的最大值里的最小值。

参考代码

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

constexpr int N = 3507;
int T, n, m, k;
int a[N];

void solve() {
	cin >> n >> m >> k;
	int ans = 1, w = min(m - 1, k);
	m -= w + 1;
	for (int i = 0; i < n; ++ i) cin >> a[i];
	for (int i = 0; i <= w; ++ i) {
		int left = i, right = n - w + i - 1;
		int res = 1e9;
		for (int j = 0; j <= m; ++ j) res = min(res, max(a[left + j], a[right - m + j]));
		ans = max(ans, res);
	}
	cout << ans << '\n';
} 

int main() {
	ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
	cin >> T;
	while (T --) {
		solve();
	}
	return 0;
}

posted on 2024-12-06 23:13  RomanLin  阅读(15)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3