ZOJ 3612 && HDU 4864 (multiset 的应用)

来源:互联网 发布:杨洋419事件始末知乎 编辑:程序博客网 时间:2024/05/21 06:38

ZOJ 3612

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4736

题意:在进行add和remove等操作下,找出这些数中的中位数

思路:利用multiset可以对用指针对中位数进行跟踪,如果共有偶数个数,让指针指向相对较小的那个数


#include <iostream>#include <algorithm>#include <stdio.h>#include <string.h>#include <set>#include <iterator>#include <functional>using namespace std;typedef long long int ll;multiset <ll> ms;multiset <ll> :: iterator it, tt;multiset <ll> :: iterator p;int main(){    int t;    scanf("%d", &t);    while(t--)    {        ms.clear();        int n;        char s[20];        int a;        scanf("%d", &n);        while(n--)        {            scanf("%s%d", s, &a);            if(!strcmp(s, "add"))            {                ms.insert(a);                if(ms.size() == 1)                    it = ms.begin();                else                {                    if(ms.size() % 2 && a >= *it)                        it++;                    if(ms.size() % 2 == 0 && a < *it)                        it--;                }            }            else            {                p = ms.find(a);                if(p == ms.end())                {                    printf("Wrong!\n");                    continue;                }                else                {                    if(*it == a)                    {                        p = it;                        if(ms.size() % 2 == 0)                            it++;                        else                            it--;                    }                    else                    {                        if(ms.size() % 2 && a > *it)                            it--;                        if(ms.size() % 2 == 0 && a < *it)                            it++;                    }                    ms.erase(p);                }            }            if(ms.empty())                printf("Empty!\n");            else            {                if(ms.size() % 2)                    printf("%lld\n", *it);                else                {                    tt = it;                    tt++;                    ll ans = *it + *tt;                    if(ans % 2 == 0)                        printf("%lld\n", ans / 2);                    else                        printf("%.1lf\n", 1.0 * ans / 2);                }            }        }    }    return 0;}


HDU 4864(多校第一场)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4864

题意:在一定量的机器和任务中找出 最好的策略使得能在完成最多任务的基础上获得最多的钱,一个机器想完成某任务,必须工作时间>=该任务时间,且等级>=该任务等级,一台机器一天只能工作一次

思路:贪心,在先将机器和任务都按等级进行排序,然后对于每台机器找出符合上述两条件的最合适的任务(对于每项任务,由于钱与机器无关,所以每项任务要派低级的机器去完成),注意upper_bound()和lower_bound()的应用


#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <set>using namespace std;const int MAX = 1e5 + 10;typedef long long ll;struct node{    ll x, y;    bool operator < (const node &a ) const    {        return x  < a.x || (x == a.x && y < a.y);    }};struct node1{    ll x, y;    bool operator < (const node1 &a ) const    {        return y < a.y || (y == a.y && x < a.x);    }};int N, M;node1 mac[MAX], task[MAX];void solve(){    int j = 1;    int cnt = 0;    ll ans = 0;    multiset <node> s;    for (int i = 1; i <= N; ++i)    {        while (j <= M && task[j].y <= mac[i].y )        {            s.insert((node)            {                task[j].x, task[j++].y            });        }        multiset <node>::iterator it = s.upper_bound( (node)        {            mac[i].x, mac[i].y        });        if (it != s.begin())        {            --it;            ans += 500 * (it -> x) + 2 * (it -> y);            ++cnt;            s.erase(it);        }    }    printf("%d %I64d\n", cnt, ans);}int main(){    while (scanf("%d%d", &N, &M) != EOF)    {        for (int i = 1; i <= N; ++i) scanf("%I64d%I64d", &mac[i].x, &mac[i].y);        for (int i = 1; i <= M; ++i) scanf("%I64d%I64d", &task[i].x, &task[i].y);        sort(mac + 1, mac + 1 + N);        sort(task + 1, task + 1 + M);        solve();    }    return 0;}


0 0
原创粉丝点击