题目:
给出2*n个矩形(给出长和宽),问前n个矩形能够套上最多多少个后n个矩形
分析:
把前n个矩形与后n个矩形分开在两数组中,然后分别先对长x(或宽)排序,排序结束后,只需要满足另外一个条件y就行。
在这里我们利用贪心的思想,每次从后n个矩形中满足x1>=x2且y2值尽可能最大,要维护y2值最大,我们可以使用平衡树(SBT、AVL、TREAP)或者Splay来维护都行,另外可利用STL的福利,直接调用multiset<int> s;维护即可,具体的应用请百度、谷歌,代码如下:
稍后我把SBT的弄上来
View Code
SBT的如下:
View Code
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 6 using namespace std; 7 8 const int X = 100010; 9 const int inf = 2e9; 10 11 int n,root,tol; 12 13 struct qq{ 14 int x,y; 15 friend bool operator < (qq a,qq b){ 16 return a.x<b.x||(a.x==b.x&&a.y<b.y); 17 } 18 }a[X],b[X]; 19 20 struct node{ 21 int val,l,r,s; 22 void init(int _val){ 23 l = r = 0; 24 s = 1; 25 val = _val; 26 } 27 }sbt[X]; 28 29 void left_rotate(int &t){ 30 int k = sbt[t].r; 31 sbt[t].r = sbt[k].l; 32 sbt[k].l = t; 33 sbt[k].s = sbt[t].s; 34 sbt[t].s = sbt[sbt[t].l].s+sbt[sbt[t].r].s+1; 35 t = k; 36 } 37 38 void right_rotate(int &t){ 39 int k = sbt[t].l; 40 sbt[t].l = sbt[k].r; 41 sbt[k].r = t; 42 sbt[k].s = sbt[t].s; 43 sbt[t].s = sbt[sbt[t].l].s+sbt[sbt[t].r].s+1; 44 t = k; 45 } 46 47 void maintain(int &t,bool ok){ 48 if(!ok){ 49 if(sbt[sbt[sbt[t].l].l].s>sbt[sbt[t].r].s) 50 right_rotate(t); 51 else if(sbt[sbt[sbt[t].l].r].s>sbt[sbt[t].r].s){ 52 left_rotate(sbt[t].l); 53 right_rotate(t); 54 } 55 else return; 56 } 57 else{ 58 if(sbt[sbt[sbt[t].r].r].s>sbt[sbt[t].l].s) 59 left_rotate(t); 60 else if(sbt[sbt[sbt[t].r].l].s>sbt[sbt[t].l].s){ 61 right_rotate(sbt[t].r); 62 left_rotate(t); 63 } 64 else return; 65 } 66 maintain(sbt[t].l,0); 67 maintain(sbt[t].r,1); 68 maintain(t,0); 69 maintain(t,1); 70 } 71 72 void insert(int &t,int val){ 73 if(!t){ 74 t = ++tol; 75 sbt[t].init(val); 76 return; 77 } 78 sbt[t].s++; 79 if(val<sbt[t].val) 80 insert(sbt[t].l,val); 81 else 82 insert(sbt[t].r,val); 83 maintain(t,val>=sbt[t].val); 84 } 85 86 int del(int &t,int val){ 87 if(!t) 88 return 0; 89 sbt[t].s--; 90 if(sbt[t].val==val||(val<sbt[t].val&&!sbt[t].l)||(val>sbt[t].val&&!sbt[t].r)){ 91 if(sbt[t].l&&sbt[t].r){ 92 int pos = del(sbt[t].l,val+1); 93 sbt[t].val = sbt[pos].val; 94 return pos; 95 } 96 else{ 97 int pos = t; 98 t = sbt[t].l+sbt[t].r; 99 return pos; 100 } 101 } 102 else 103 return del(val<sbt[t].val?sbt[t].l:sbt[t].r,val); 104 } 105 106 int get_pre(int t,int val){ 107 if(!t) 108 return inf; 109 if(val<sbt[t].val) 110 return get_pre(sbt[t].l,val); 111 else if(val==sbt[t].val) 112 return val; 113 else{ 114 int temp = get_pre(sbt[t].r,val); 115 return temp==inf?sbt[t].val:temp; 116 } 117 } 118 119 int main(){ 120 freopen("sum.in","r",stdin); 121 int ncase; 122 cin>>ncase; 123 while(ncase--){ 124 cin>>n; 125 for(int i=0;i<n;i++) 126 scanf("%d%d",&a[i].x,&a[i].y); 127 for(int i=0;i<n;i++) 128 scanf("%d%d",&b[i].x,&b[i].y); 129 sort(a,a+n); 130 sort(b,b+n); 131 int j = 0; 132 int ans = 0; 133 root = tol = 0; 134 for(int i=0;i<n;i++){ 135 while(j<n&&b[j].x<=a[i].x){ 136 insert(root,b[j].y); 137 j++; 138 } 139 if(sbt[root].s==0) 140 continue; 141 int temp = get_pre(root,a[i].y); 142 if(temp<=a[i].y){ 143 ans++; 144 del(root,temp); 145 } 146 } 147 cout<<ans<<endl; 148 } 149 return 0; 150 }
1 #include <set> 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 7 using namespace std; 8 9 const int maxn = 1e6+5; 10 11 struct node{ 12 int x,y; 13 friend bool operator < (node a,node b){ 14 return a.x<b.x||(a.x==b.x&&a.y<b.y); 15 } 16 }a[maxn],b[maxn]; 17 18 multiset<int> s; 19 int n; 20 21 int main(){ 22 freopen("sum.in","r",stdin); 23 int ncase; 24 cin>>ncase; 25 while(ncase--){ 26 cin>>n; 27 for(int i=0;i<n;i++) 28 scanf("%d%d",&a[i].x,&a[i].y); 29 for(int i=0;i<n;i++) 30 scanf("%d%d",&b[i].x,&b[i].y); 31 sort(a,a+n); 32 sort(b,b+n); 33 set<int>::iterator it; 34 s.clear(); 35 int j = 0; 36 int ans = 0; 37 for(int i=0;i<n;i++){ 38 while(j<n&&b[j].x<=a[i].x){ 39 s.insert(b[j].y); 40 j++; 41 } 42 if(s.size()==0) 43 continue; 44 it = s.upper_bound(a[i].y); 45 if(it!=s.begin()){ 46 ans++; 47 it--; 48 s.erase(it); 49 } 50 } 51 cout<<ans<<endl; 52 } 53 return 0; 54 }