2022.10.28每日刷题打卡

Number Game

题意不多赘述,可以参考洛谷的翻译。

思路:贪心地去思考,Bob每次删除序列中的最小的元素更符合Bob的最优选择,由此我们可以选择模拟这个游戏的过程,Alice每轮删除最大的x(x<=k-i+1),如果没有x那么Alice输。

好了,这是在做这道题前要整理出来的,那么接下来怎么去找出最大的k呢,由题意1<=k<=n很显然可以用二分查找去找到答案k,那么二分区间的条件显然就是Alice能不能赢,这里面我们可以对模拟的过程进行简化,由上x<=k-i+1,每次找到序列a中符合该条件最大的x,那么更大的(即序列中大于x的)显然无法去考虑,所以在处理这个过程我们可以选择双指针或模拟栈。

AC代码:

#include <bits/stdc++.h>

int main () {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	int t;
	std::cin >> t;
	while (t--) {
		int n;
		std::cin >> n;
		std::vector<int> a(n), b(n);
		for (int &ai : a) {
			std::cin >> ai;
		}
		std::function<int(int)> judge = [&](int x) {
			b = a;
			int j = x;
			while (j >= 1) {
				while (!b.empty() && b.back() > j) {
					b.pop_back();
				}
				if (b.empty()) {
					return 0;
				}
				b.pop_back();
				if (!b.empty()) {
					b.erase(b.begin());
				}
				j--;
			}
			return 1;
		};
		std::sort(a.begin(), a.end());
		int l = 0, r = n + 1;
		while (l + 1 < r) {
			int mid = (l + r) >> 1;
			if (judge(mid)) l = mid;
			else r = mid;
		}
		std::cout << l << "\n";
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值