[uva_la7146 Defeat the Enemy(2014 shanghai onsite)]贪心

题意:我方n个军队和敌方m个军队进行一对一的对战,每个军队都有一个攻击力和防御力,只要攻击力不小于对方就可以将对方摧毁。问在能完全摧毁敌方的基础上最多能有多少军队不被摧毁。

思路:按防御力从大到小考虑敌方的军队由我们哪只军队去摧毁,对每个敌方军队,维护我方军队可以摧毁它的集合,用S表示,从大到小考虑保证了S更容易维护,只需要记录防御力就够了,不需要大量的删除操作。我们需要选择S中防御力大于当前敌方军队且最小的军队,那么这个军队是可以摧毁敌方军队而自己不被摧毁的。如果这样的军队不存在,那么直接用S中防御力最小的去和敌方军队同归于尽,因为这样做到了自己损失最小。如果中间某个时刻S为空了,则说明我方派不出摧毁当前敌方军队的军队了。

(忠告:维护集合时先想想是用set呢还是multiset,否则又该怀疑数据有问题了。。。)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#pragma comment(linker, "/STACK:10240000")
#include <bits/stdc++.h>
using namespace std;

#define X                   first
#define Y                   second
#define pb                  push_back
#define mp                  make_pair
#define all(a)              (a).begin(), (a).end()
#define fillchar(a, x)      memset(a, x, sizeof(a))

typedef long long ll;
typedef pair<int, int> pii;

#ifndef ONLINE_JUDGE
namespace Debug {
void print(){cout<<endl;}template<typename T>
void print(const T t){cout<<t<<endl;}template<typename F,typename...R>
void print(const F f,const R...r){cout<<f<<", ";print(r...);}template<typename T>
void print(T*p, T*q){int d=p<q?1:-1;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;}
}
#endif // ONLINE_JUDGE
template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);}
template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);}
/* -------------------------------------------------------------------------------- */

const int maxn = 1e5 + 7;

multiset<int> s;
int n, m;
pii a[maxn], b[maxn];

void work() {
    int ans = n - m;
    s.clear();
    int now = n - 1;
    for (int i = m - 1; i >= 0; i --) {
        while (now >= 0 && a[now].X >= b[i].X) s.insert(a[now --].Y);
        if (!s.size()) {
            puts("-1");
            return ;
        }
        multiset<int>::iterator iter = s.upper_bound(b[i].Y);
        if (iter == s.end()) s.erase(s.begin());
        else {
            ans ++;
            s.erase(iter);
        }
    }
    printf("%d\n", ans);
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
#endif // ONLINE_JUDGE
    int T, cas = 0;
    cin >> T;
    while (T --) {
        printf("Case #%d: ", ++ cas);
        cin >> n >> m;
        for (int i = 0; i < n; i ++) {
            scanf("%d%d", &a[i].X, &a[i].Y);
        }
        for (int i = 0; i < m; i ++) {
            scanf("%d%d", &b[i].Y, &b[i].X);
        }
        if (n < m) puts("-1");
        else {
            sort(a, a + n);
            sort(b, b + m);
            work();
        }
    }
    return 0;
}
时间: 2024-08-09 02:01:17

[uva_la7146 Defeat the Enemy(2014 shanghai onsite)]贪心的相关文章

[LA7139 Rotation(2014 shanghai onsite)]二维树状数组

题意:有一个n*m的矩形,一辆车从左上角出发,沿一条路径走,路径是由矩形上每个单元格的边构成的,最后回到左上角,求车子在每个格子转过圈数的平方和. 思路:假设需要记录每个格子转的顺时针的圈数(为负表示转的逆时针),可以考虑车子每次移动对各个格子的贡献: 车子左移,路径上方所有格子转的圈数+1,路径下方所有格子-1,而上方和下方所有格子都形成大的矩形,于是相当于每次对矩形区域的格子全部执行加减操作. 车子右移,上方-1,下方+1. 车子上移,左边-1,右边+1. 车子下移,左边+1,右边-1. 对

I - Defeat the Enemy UVALive - 7146 二分 + 贪心

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5158 这样的受到两个东西限制的,很容易想到要排序,然后加进去multiset,加的时候保证一个key是成立的,就转化为一个key的问题了. 这题需要打死m个全部的军队. 那么应该是枚举m个军队,去找一个n打死它,或者同归于尽. 开始的时候我是枚举n去选m了,这是错误的. 因为

UVA LIVE 7146 Defeat the Enemy

这个题跟codeforces 556 D Case of Fugitive思路一样 关于codeforces 556 D Case of Fugitive的做法的链接http://blog.csdn.net/stl112514/article/details/46868749 题意大概我方有n个军队,敌方有m个军队,军队有两个属性:攻击力和防御力 一个军队能打败另一个军队的条件:一军队攻击力不低于另一个军队防御力 大概是2014上海区域赛最简单的一个题? #include<map> #incl

UVALive 7146 Defeat The Enemy

Defeat The Enemy Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu Long long ago there is a strong tribe living on the earth. They always have wars and eonquer others. One day, there is another tribe become their target. The stron

HDU 4864 Task(2014多校--贪心)

Task 比赛当时思路想的差不多,感觉能过的,该处理的也都处理到了,最后还是没过,可能是二分写错了吧-.- 大意:给你n个机器,m个要完成的任务,每个机器跟任务都有两个属性,机器是最大工作时间跟等级,任务是需要工作的时间跟等级.完成一个任务可以得到500*(工作时间)+2*(等级)的报酬.完成任务的条件是机器的工作时间满足任务的需要,等级要大于等于任务的等级,一个机器只能用一次,一个任务也只能用一个机器去完成.需要进行策略选择,使得完成更多的任务. 思路:开始想的就是贪心,也想到了贪心的时候时间

2014上海区域赛 I题 Defeat the Enemy 离线读入 在线更新 线段树套优先队列

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5158 UVALive 7146 题意 自己有n个军队 敌方有m个军队 每个军队都有攻击力和防守力两种属性 当一方的攻击力>=对方的防御力时 可以把对方杀掉 在一次战斗中有可能出现双方都死了或者双方都没死的情况 另外要求己方不能有两只不同军队跟对方的同一只军队交

BZOJ 3721 PA 2014 Final Bazarek 贪心

题目大意:有n件商品,选出其中的k个,要求它们的总价为奇数,求最大可能的总价. 思路:一个O(n)的贪心,先排序,然后O(n)预处理每个节点之前出现的最大奇数和偶数,和每一个节点之后出现的最小的奇数或者偶数,之后每个询问O(1)判断一下.注意初值. CODE: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 1000010 #d

2014 Shanghai Regional Room Assignment (DP)

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5155 题意:有n个颜色的球,其中有k对球颜色相同,别的都是完全不同的.给m个盒子,每个盒子的容量为c[i],有sum{c[i]}=n.问:有多少种姿势可以把n个球全部放入盒子中. dp[i][j] 表示 在填充完前i个盒子后,还剩下j对twins的方案数.那么最终答

BZOJ 3671 NOI 2014 随机数生成器 贪心

题目大意:实在是太难说明了,自己看pdf吧.. 思路:优先按照它说明的方法处理数组,然后为了让数列中尽可能多的出现小的数字,所以1是必须要出现的,这样才能使整个数列的排序后字典序最小.我们思考,如果2也能在这个数列中那就最好不过了,但是2有可能不在这个数列里,就是2在走了1就不可能走的地方的话,就不能走2了.所以从小到大枚举数字,如果当前数字能走,就输出,然后标记所有走了这个节点就不能走的节点.空间比较紧,5000*5000可以开int*2+bool*1,极限了.. CODE: #include