UVALive7146 Defeat the Enemy
题目
见链接。
题解
知识点:贪心,STL。
首先要保证我方军队能消灭对方军队才行,因此只要我们按攻击力从大到小排,对方按防御力从大到小排,从大到小遍历,用我方所有攻击力大于敌方目前防御力军队中的一个打,就能保证对方小的防御力不会先把我方大的攻击力用掉,导致对方大的防御力没有办法消灭,即能消灭就一定消灭,不能就一定不能返回 。
现在考虑保证我方被消灭最少,发现如果在我方攻击力大于对方防御力的军队里面选,一定优先选择防御力刚好大于对方攻击力的军队,这样就可以保证大的防御力能保留,小的防御力不会被消灭;但如果最大的防御力都小于等于对方攻击力,那一定选择防御力最小的军队打,因为既然都会同归于尽,那么就让大的防御力保留,把最小的防御力同归于尽,保证后面有足够的防御力。因此我们这时候需要一个容器能够排序,查询,删除,插入,可以有相同元素,那么就要选择 存储我方军队防御力。
于是,每次先把大于等于的军队放入多重集,如果没有则返回 。然后查找一个刚好防御力大于其攻击力的军队打,否则就用防御力最小的打,然后军队存活数量减一。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> #define ll long long using namespace std; struct node { int atk, def; }a[100007], b[100007]; bool solve() { int n, m; cin >> n >> m; for (int i = 0;i < n;i++)cin >> a[i].atk >> a[i].def; for (int i = 0;i < m;i++)cin >> b[i].def >> b[i].atk; sort(a, a + n, [&](node a, node b) {return a.atk > b.atk;}); sort(b, b + m, [&](node a, node b) {return a.def > b.def;}); int cnt = n; multiset<int> ms; for (int i = 0, j = 0;j < m;j++) { while (i < n && a[i].atk >= b[j].def) ms.insert(a[i++].def); if (ms.empty()) return false; auto it = ms.upper_bound(b[j].atk); if (it == ms.end()) { ms.erase(ms.begin()); cnt--; } else ms.erase(it); } cout << cnt << '\n'; return true; } int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int t = 1, cnt = 1; cin >> t; while (t--) { cout << "Case #" << cnt++ << ":"; if (!solve()) cout << -1 << '\n'; } return 0; }
本文来自博客园,作者:空白菌,转载请注明原文链接:https://www.cnblogs.com/BlankYang/p/16461607.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧