小z的卡片 | ||||||
|
||||||
Description | ||||||
小w和小z想到了一个新游戏,在这个游戏中他们各有N个卡片。小w想去使用她的卡片去覆盖小z的卡片。 卡片A能覆盖卡片B的条件是卡片A的高不小于卡片B的高同时卡片A的宽不小于卡片B的宽。 现在请计算出小w的牌最多能覆盖小z的牌的数量。注意牌只能被使用一次,并且牌不能被旋转。 |
||||||
Input | ||||||
第一行是一个整数t代表测试数据组数。 对于每组测试数据第一行是一个整数n(n<=100000)代表卡片数量。 接下来n行每行两个整数h(h<=1000000000)和w(w<=1000000000)代表小w的卡片的高和宽。 在接下来n行每行两个整数h(h<=1000000000)和w(w<=1000000000)代表小z的卡片的高和宽。 |
||||||
Output | ||||||
对于每组测试数据,输出小w的牌最多能覆盖小z的牌的数量。 | ||||||
Sample Input | ||||||
2 2 1 2 3 4 2 3 4 5 3 2 3 5 7 6 8 4 1 2 5 3 4 |
||||||
Sample Output | ||||||
1 2 |
一开始相出的办法超时了,方法是,对小z的牌排序,然后对于小w的每个牌,找到宽度最接近的,然后覆盖它
代码:
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> #include<queue> using namespace std; struct node { int height,width; int key; } a[100001],b[100001]; bool cmp(node x,node y) { return x.height<y.height; } int main() { int T; while(~scanf("%d",&T)) { while(T--) { int n; scanf("%d",&n); int i; for(i=0;i<n;i++) { scanf("%d%d",&a[i].height,&a[i].width); } for(i=0;i<n;i++) { scanf("%d%d",&b[i].height,&b[i].width); b[i].key=0; } sort(b,b+n,cmp); int sum=0,j; int width_Max=1000000000; int width_Mark; for(i=0;i<n;i++) { width_Max=1000000000; for(j=0;j<n;j++) { if(b[j].key==1) { continue; } if(b[j].height>a[i].height) { break; } else if(b[j].height<=a[i].height&&b[j].width<=a[i].width) { if(a[i].width-b[j].width<width_Max) { width_Max=a[i].width-b[j].width; width_Mark=j; } } } if(width_Max!=1000000000) { b[width_Mark].key=1; sum++; } } printf("%d\n",sum); } } return 0; }
时间复杂度是n*n,这样会超时,
所以
把所有卡片放在一起排序,然后把排在前面的小z的卡片装在容器里,遇见小w的卡片,就在容器里找一个最大宽度的可覆盖的卡片
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> #include<queue> #include<set> using namespace std; struct node { int height,width; int key; }p[200001]; bool cmp(node x,node y) { if(x.height!=y.height) { return x.height<y.height; } return x.key>y.key; } multiset <int> s; multiset <int> :: iterator it; int main() { int T; while(~scanf("%d",&T)) { while(T--) { int n; scanf("%d",&n); int i;; for(i=0;i<2*n;i++) { scanf("%d%d",&p[i].height,&p[i].width); if(i>=n) { p[i].key=1; } else { p[i].key=0; } } s.clear(); sort(p,p+2*n,cmp); int sum=0; for(i=0;i<2*n;i++) { if(p[i].key==1) { s.insert(p[i].width); } else if(!s.empty()) { if(*s.begin()<=p[i].width) { it=s.upper_bound(p[i].width); it--; s.erase(it); sum++; } } } printf("%d\n",sum); } } return 0; }