zoukankan      html  css  js  c++  java
  • hdu 1677 Nested Dolls (Greedy + Treap)

    http://acm.hdu.edu.cn/showproblem.php?pid=1677

      题意是,给出一些矩形的长和宽,如果l1<l2且w1<w2,那么矩形2可以套在矩形1外面。问最优的套法下,最后可以剩下多少个矩形。

      我想到的一个做法是,利用Treap来对当前最外层矩形是哪些进行维护。首先我们先按照宽(第二关键字)递增排序,如果相同就按长(第一关键字)递增排序。然后在构建出一棵空的Treap,按顺序插入到树中去。对于每一次插入,找到最大的可以被当前矩形覆盖的一个矩形,然后更新成新的矩形。如果找不到这样的矩形,就直接插入当前矩形。最后Treap的大小就是所需的答案。

    代码如下:

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <cstring>
      4 #include <iostream>
      5 #include <ctime>
      6 
      7 using namespace std;
      8 
      9 typedef pair<int, int> PII;
     10 #define MPR make_pair
     11 
     12 struct treapNode {
     13     treapNode *c[2];
     14     PII key;
     15     int fix, sz;
     16     treapNode() {}
     17     treapNode(PII k) : key(k) {
     18         fix = rand();
     19         sz = 1;
     20         c[0] = c[1] = 0;
     21     }
     22 } ;
     23 typedef treapNode TN;
     24 
     25 struct Treap {
     26     TN *root;
     27     int sz;
     28     Treap() {
     29         srand(time(0));
     30         root = 0;
     31         sz = 0;
     32     }
     33     void rotate(TN *&rt, bool l) {
     34         bool r = !l;
     35         TN *p = rt->c[l];
     36         rt->c[l] = p->c[r];
     37         p->c[r] = rt;
     38         p->sz = rt->sz;
     39         rt->sz = (rt->c[0] ? rt->c[0]->sz : 0) + (rt->c[1] ? rt->c[1]->sz : 0) + 1;
     40         rt = p;
     41     }
     42     void ins(TN *&rt, TN *x) {
     43         if (!rt) {
     44             rt = x;
     45             return ;
     46         }
     47         rt->sz++;
     48         if (x->key < rt->key) {
     49             ins(rt->c[0], x);
     50             if (rt->c[0]->fix > rt->fix) {
     51                 rotate(rt, 0);
     52             }
     53         } else {
     54             ins(rt->c[1], x);
     55             if (rt->c[1]->fix > rt->fix) {
     56                 rotate(rt, 1);
     57             }
     58         }
     59     }
     60     void ins(PII k) {
     61         TN *tmp = new TN(k);
     62         sz++;
     63         ins(root, tmp);
     64     }
     65     void delT(TN *&rt) {
     66         if (!rt) return ;
     67         delT(rt->c[0]);
     68         delT(rt->c[1]);
     69         delete rt;
     70     }
     71     void delT() {
     72         delT(root);
     73         sz = 0;
     74     }
     75     void del(TN *&rt, PII key) {
     76 //        cout << "key " << key.first << ' ' << key.second << ' ' << rt->key.first << ' ' << rt->key.second << endl;
     77         if (!rt) return ;
     78         if (key < rt->key) del(rt->c[0], key);
     79         else if (key > rt->key) del(rt->c[1], key);
     80         else {
     81 //            cout << "not root" << endl;
     82             if (!rt->c[0] && !rt->c[1]) {
     83                 delete rt;
     84                 rt = 0;
     85                 return ;
     86             } else if (!rt->c[0]) {
     87                 TN *tmp = rt;
     88                 rt = rt->c[1];
     89                 delete tmp;
     90             } else if (!rt->c[1]) {
     91                 TN *tmp = rt;
     92                 rt = rt->c[0];
     93                 delete tmp;
     94             } else {
     95 //                cout << "here" << endl;
     96                 if (rt->c[0]->fix < rt->c[1]->fix) {
     97                     rotate(rt, 1);
     98                     del(rt->c[0], key);
     99                 } else {
    100                     rotate(rt, 0);
    101                     del(rt->c[1], key);
    102                 }
    103             }
    104         }
    105         rt->sz = (rt->c[0] ? rt->c[0]->sz : 0) + (rt->c[1] ? rt->c[1]->sz : 0) + 1;
    106     }
    107     void del(PII key) {
    108         del(root, key);
    109         sz--;
    110     }
    111     PII find(TN *rt, PII key) {
    112         if (!rt) return MPR(-1, -1);
    113         if (rt->key.first >= key.first) {
    114             return find(rt->c[0], key);
    115         } else {
    116             PII ret = find(rt->c[1], key);
    117             if (ret == MPR(-1, -1)) {
    118                 if (rt->key.first >= key.first || rt->key.second >= key.second) return find(rt->c[0], key);
    119                 return rt->key;
    120             }
    121             return ret;
    122         }
    123     }
    124     PII find(PII key) {
    125         return find(root, key);
    126     }
    127 } ;
    128 
    129 PII rec[22222];
    130 
    131 bool cmp(PII a, PII b) {
    132     if (a.second != b.second) return a.second < b.second;
    133     return a.first < b.first;
    134 }
    135 
    136 int main() {
    137 //    freopen("in", "r", stdin);
    138     int T, n;
    139     cin >> T;
    140     while (T-- && cin >> n) {
    141         Treap treap = Treap();
    142         for (int i = 0; i < n; i++) {
    143 //            cin >> rec[i].first >> rec[i].second;
    144             scanf("%d%d", &rec[i].first, &rec[i].second);
    145         }
    146         sort(rec, rec + n, cmp);
    147         for (int i = 0; i < n; i++) {
    148 //            cout << rec[i].first << ' ' << rec[i].second << endl;
    149             PII tmp = treap.find(rec[i]);
    150 //            cout << "tmp " << tmp.first << ' ' << tmp.second << endl;
    151             if (tmp == MPR(-1, -1)) {
    152                 treap.ins(rec[i]);
    153             } else {
    154                 treap.del(tmp);
    155                 treap.ins(rec[i]);
    156             }
    157         }
    158         cout << treap.sz << endl;
    159 //        treap.delT();
    160     }
    161     return 0;
    162 }
    View Code

    ——written by Lyon

  • 相关阅读:
    关于生成二维码的相关参考资料
    C#生成二维码的方法
    .NET 二维码生成(ThoughtWorks.QRCode)
    微信扫描二维码登录网站技术原理
    C# ArrayList的用法
    C#多线程编程
    c#使用多线程的几种方式示例详解
    解决Winform应用程序中窗体背景闪烁的问题
    C# 线程调用主线程中的控件
    30、网络编程
  • 原文地址:https://www.cnblogs.com/LyonLys/p/hdu_1677_Lyon.html
Copyright © 2011-2022 走看看