hdu 4268 alice and bob

Alice and Bob

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1545    Accepted Submission(s): 570


Problem 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

题意:

alice的卡片要覆盖bob的卡片,则alice的卡片的h,w都得大于等于bob的h,w,求alice最多覆盖几张卡片

解析:

就是很明显的贪心,但是注意要综合考虑h和w,此题就是把他们全都按照先h后w的方法从小到大排序,然后就枚举allice的卡片,对于每个alice的卡片都在bob的卡片中找符合条件且w最大的卡片覆盖,这样才是每一步都最优。因为后面的卡片h必然大于前面的卡片,所以只要把最大的w覆盖掉即可。

因为每一次找到一个bob卡片的w都要重新排序,所以可以用堆排来更新,这样的话就可以用stl中的set头文件了

#include
#include
#include
#include
#define Max 100010
using namespace std;

multisets;//应该用multiset,因为set里面不能出现重复的值
struct cardt
{
	int h,w,flag;	//flag的值为1代表是Alice,为0代表是Bob
}card[2*Max];

bool cmp(cardt a,cardt b)//先按照h,后按照w从小到大排序
{
	if(a.h != b.h ) return a.h < b.h;
	else if(a.w != a.w)return a.w < b.w;
	else return a.flag < b.flag;
}

int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int count = 0;
		memset(card,0,sizeof(card));
		int n;
		scanf("%d",&n);
		for(int i = 1; i <= 2*n ; i ++)
		{
			scanf("%d%d",&card[i].h ,&card[i].w );
			i <= n ? card[i].flag = 1:card[i].flag = 0;
		}
		sort(card+1,card+2*n+1,cmp);//这里是把他们全都放在一起排序,更方便

		s.clear();
		for(int i = 1 ; i <= 2*n ; i ++)
		{
			if(card[i].flag == 0)
				s.insert(card[i].w);
			else if(card[i].flag == 1)
			{
				if(!s.empty() && *s.begin() <= card[i].w )	//如果最小的一个仍然大于card[i].w就说明其不能覆盖
				{
					multiset::iterator t ;//迭代器的固定格式,若不存在就返回s.end(),
					//s.end()返回最后一个元素的下一位置的指针(set为空时,end()=begin())
					t = s.upper_bound(card[i].w);
					//那么若set只有一个元素的话,则不存在>card[i].w的值,t返回end(),t--正好等于该元素
					t--;
					s.erase(t);
					count++;
				}
			}
		}
		printf("%d\n",count);
	}
	return 0;
}


你可能感兴趣的:(ACM(old))