• G. Of Zorcs and Axes 二分 + 贪心 —— STL的用法


    http://codeforces.com/gym/101149/problem/G

    一开始还以为要用二分图去做,但是复杂度也太高了,O(n * m)的话直接爆炸。

    考虑贪心,考虑第i个东西优先选一个能选的,而且这个东西的值尽量小。

    就是如果要<3, 3>的话,我希望找到有序对<x, y>,其中x和y都最接近3, 3

    那么这里就涉及到同时排序两个数,就是这两个数的优先级一样,而且二分找的时候也要同时比较两个数了

    一开始还想用set的,但是这样重载运算符的set我没用过,重载成 return a < rhs.a && b < rhs.b; 这样会把有些set的元素载入不了,不知道为何,希望有大牛指点一二。

    那么可以这样去想,先对x排序,如果x相同再对y排序,全部相同就按照被选的那个优先,就是m那堆数字有先。

    这样做有什么好处呢?可以维护一个set,每次如果是m那堆数字的话,就扔去set那里,如果不是,就从set里面找,找的时候只需要比较y就行了,因为x已经保证严格成立了。

    最后说一下set那里,自己写一个比较函数的话,就要考虑重复的元素,因为重复的元素会被自动删除的,但是我本来结构体那里就有了个id这个值,id是保证不同的了,id是我用来记录答案的,但是它还是去重了。现在试了发现,如果想id不同,就当成不同的元素的话,就要在你的cmp那里把id加上去比较,

    这里坑了我太久了,一直wa9、

    给个数据吧

    6
    2 5
    4 3
    4 3
    4 3
    4 3
    4 2
    6
    5 6
    4 3
    4 3
    4 2
    4 3
    4 3

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    const int maxn = 5e5 + 20;
    struct node {
        int a, b, id;
        int flag;
        node() {}
        node(int aa, int bb, int iidd, int Orz_zk) : a(aa), b(bb), id(iidd), flag(Orz_zk) {}
        bool operator < (const struct node & rhs) const {
            if (a != rhs.a) return a < rhs.a;
            else if (b != rhs.b) return b < rhs.b;
            else return flag < rhs.flag;
        }
    }arr[maxn];
    struct cmp {
        bool operator() (struct node a, struct node b) {
            if (a.b != b.b) {
                return a.b < b.b;
            } else if (a.a != b.a) return a.a < b.a;
            else if (a.flag != b.flag) return a.flag < b.flag; //找的时候flag是0,也要处理
            else return a.id < b.id; //注意,这个一定要有
        }
    };
    set<struct node, cmp>ss;
    int ans[maxn];
    void work() {
        int n;
        cin >> n;
        for (int i = 1; i <= n; ++i) {
            cin >> arr[i].a >> arr[i].b;
            arr[i].id = i;
            arr[i].flag = 0;
        }
        int m;
        cin >> m;
        for (int i = 1; i <= m; ++i) {
            cin >> arr[i + n].a >> arr[i + n].b;
            arr[i + n].flag = 1;
            arr[i + n].id = i;
        }
        sort(arr + 1, arr + 1 + n + m);
    //    for (int i = m + n; i >= 1; --i) {
    //        cout << arr[i].a << " " << arr[i].b << " " << arr[i].flag << " " << arr[i].id << endl;
    //    }
    //    cout << endl;
        set<struct node> :: iterator it;
        for (int i = m + n; i >= 1; --i) {
    //        for (it = ss.begin(); it != ss.end(); ++it) {
    //            cout << it->a << " " << it->b << " " << it->id << endl;
    //        }
    //        cout << endl;
    //        cout << arr[i].a << " " << arr[i].b << " " << arr[i].flag << endl;
            if (arr[i].flag) {
                ss.insert(arr[i]);
                continue;
            }
            if (ss.size() == 0) {
                cout << -1 << endl;
                return;
            }
            it = ss.lower_bound(arr[i]);
            if (it == ss.end()) {
                cout << -1 << endl;
                return;
            }
            ans[arr[i].id] = it->id;
            ss.erase(it);
        }
        for (int i = 1; i <= n; ++i) {
            if (ans[i] == 0) while(1);
            cout << ans[i] << " ";
        }
    }
    int main() {
    #ifdef local
        freopen("data.txt","r",stdin);
    #endif
        IOS;
        work();
        return 0;
    }
    View Code
  • 相关阅读:
    记第一场cf比赛(Codeforces915)
    Uva11468:Substring
    Uva11732:"strcmp()" Anyone?
    Uva1014:Remember the Word
    洛谷P2502:[HAOI2006]旅行
    bzoj3677: [Apio2014]连珠线
    bzoj4906: [BeiJing2017]喷式水战改
    海上孤独的帆
    Treap基本用法总结
    noip2017考前基础复习——数论数学
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6044994.html
Copyright © 2020-2023  润新知