HDU - 4268 Alice and Bob (set的应用)好题

HDU - 4268
Alice and Bob
Time Limit: 5000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u

Submit Status

Description

Alice and Bob's game never ends. Today, they introduce a new game. In this game, both of them have N different rectangular cards respectively. Alice wants to use his cards to cover Bob's. The card A can cover the card B if the height of A is not smaller than B and the width of A is not smaller than B. As the best programmer, you are asked to compute the maximal number of Bob's cards that Alice can cover.  
Please pay attention that each card can be used only once and the cards cannot be rotated.  
 

Input

The first line of the input is a number T (T <= 40) which means the number of test cases.  
For each case, the first line is a number N which means the number of cards that Alice and Bob have respectively. Each of the following N (N <= 100,000) lines contains two integers h (h <= 1,000,000,000) and w (w <= 1,000,000,000) which means the height and width of Alice's card, then the following N lines means that of Bob's.  
 

Output

For each test case, output an answer using one line which contains just one number.  
 

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
 

Source

2012 ACM/ICPC Asia Regional Changchun Online
先介绍一下set的相关用法:

c++ stl集合set介绍

   c++ stl集合(Set)是一种包含已排序对象的关联容器。set/multiset会根据待定的排序准则,自动将元素排序。两者不同在于前者不允许元素重复,而后者允许。

1) 不能直接改变元素值,因为那样会打乱原本正确的顺序,要改变元素值必须先删除旧元素,则插入新元素

2) 不提供直接存取元素的任何操作函数,只能通过迭代器进行间接存取,而且从迭代器角度来看,元素值是常数

3) 元素比较动作只能用于型别相同的容器(即元素和排序准则必须相同)

set模板原型://Key为元素(键值)类型

set的各成员函数列表如下:

c++ stl容器set成员函数:begin()--返回指向第一个元素的迭代器

c++ stl容器set成员函数:clear()--清除所有元素

c++ stl容器set成员函数:count()--返回某个值元素的个数

c++ stl容器set成员函数:empty()--如果集合为空,返回true

c++ stl容器set成员函数:end()--返回指向最后一个元素的迭代器

c++ stl容器set成员函数:equal_range()--返回集合中与给定值相等的上下限的两个迭代器

c++ stl容器set成员函数:erase()--删除集合中的元素

c++ stl容器set成员函数:find()--返回一个指向被查找到元素的迭代器

c++ stl容器set成员函数:get_allocator()--返回集合的分配器

c++ stl容器set成员函数:insert()--在集合中插入元素

c++ stl容器set成员函数:lower_bound()--返回指向大于(或等于)某值的第一个元素的迭代器

c++ stl容器set成员函数:key_comp()--返回一个用于元素间值比较的函数

c++ stl容器set成员函数:max_size()--返回集合能容纳的元素的最大限值

c++ stl容器set成员函数:rbegin()--返回指向集合中最后一个元素的反向迭代器

c++ stl容器set成员函数:rend()--返回指向集合中第一个元素的反向迭代器

c++ stl容器set成员函数:size()--集合中元素的数目

c++ stl容器set成员函数:swap()--交换两个集合变量

c++ stl容器set成员函数:upper_bound()--返回大于某个值元素的迭代器

c++ stl容器set成员函数:value_comp()--返回一个用于比较元素间的值的函数

#include<iostream> 
#include<set> 
using  namespace  std; 
//set插入元素操作  
int  main() 
     //定义一个int型集合对象s,当前没有任何元素.由www.169it.com搜集整理
     set< int > s; 
     s.insert(8);   //第一次插入8,可以插入  
     s.insert(1); 
     s.insert(12); 
     s.insert(6); 
     s.insert(8);    //第二次插入8,重复元素,不会插入  
     set< int >::iterator it;  //定义前向迭代器 
     //中序遍历集合中的所有元素  
     for (it=s.begin();it!=s.end();it++) 
     cout<<*it<<endl;    
     system ( "pause" ); 
     return  0; 
}
//题意:
给你n张A卡片的长和宽,再给你n张B卡片的长和宽,问最多有几对卡片是A可以包含B的,包含(A.l>=B.l&&a.w>=b.w)
//思路:
直接先将长按从大到小排序,再将A的宽逐个入集合,再模拟B的宽,一直遍历找就行了,一个set模板
#include<stdio.h>
#include<string.h>
#include<set>
#include<algorithm>
#define N 100010
using namespace std;
struct zz
{
	int l;
	int w;
}a[N],b[N];
bool cmp(zz a,zz b)
{
	if(a.l==b.l)
		return a.w>b.w;
	return a.l>b.l;
}
set<int>s;
set<int>::iterator f;
int main()
{
	int t,n,i,j,k;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		for(i=1;i<=n;i++)
			scanf("%d%d",&a[i].l,&a[i].w);
		for(i=1;i<=n;i++)
			scanf("%d%d",&b[i].l,&b[i].w);
		sort(a+1,a+n+1,cmp);sort(b+1,b+n+1,cmp);
		j=1;s.clear();
		int ans=0;
		for(i=1;i<=n;i++)
		{
			while(j<=n&&a[j].l>=b[i].l)
			{
				s.insert(a[j].w);
				j++;
			}
			f=s.lower_bound(b[i].w);
			if(f!=s.end())
			{
				ans++;
				s.erase(f);
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}

你可能感兴趣的:(HDU - 4268 Alice and Bob (set的应用)好题)