欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

H - Tokens on the Segments

程序员文章站 2022-06-02 20:30:35
...

H - Tokens on the Segments
Output
For each test case output one line containing one integer, indicating the maximum possible number of segments that have at least one token on each of them.

Sample Input

2
3
1 2
1 1
2 3
3
1 2
1 1
2 2

Sample Output

3
2

Hint

For the first sample test case, one can put three tokens separately on (1, 2), (2, 1) and (3, 3).
For the second sample test case, one can put two tokens separately on (1, 2) and (2, 3).

题意:比较难懂,
第一次输入的是x的线段范围(l1,r1) ,纵坐标为1,
第一次输入的是x的线段范围(l2,r2) ,纵坐标为2,
第一次输入的是x的线段范围(l3,r3) ,纵坐标为3,

这些线段中,往整数点上放点,每个点只能被放一次,问最多可以放多少个线段。

思路:贪心。(一直处理最小的元素)
首先用一个优先队列从小到大排个序,排完序后按照从小开始处理,
最小的左端点从1开始,初始一个mmax=0表示当前的最大值,初始一个sum表示可以选择线段的总数。
第一个操作,把队首的元素取出(每次取得都是最小的,注意这一点),然后删除队首元素,已经用过了,让他的左端点与mmax比较大小,如果比他大,说明这可线段可以放,让当前最大值等于他的左端点,sum++。如果左端点不比他大,判断是否这个左端点小于右端点,成立则左端点+1,并把它放入队列,一直循环到队列中没有元素。

AC代码:

#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
struct node{
	ll l,r;
}b;
bool operator>( node a, node b ){
     
     if( a.l== b.l ) return a.r> b.r;
    return a.l> b.l; 
}
priority_queue< node ,vector<node>,greater<node> > q;
int main()
{
	ll t;
	cin>>t;
	while(t--)
	{
		ll n;
		cin>>n;
		for(int i=1;i<=n;i++)
		{
			cin>>b.l>>b.r;
			q.push(b);
		}
		ll num=0,mmax=0;
		while(!q.empty())
		{
			b=q.top();
			q.pop();
			if(b.l>mmax)
			{
				mmax=b.l;
				num++;
			}
			else
			{
				if(b.l<b.r)
				{
					b.l++;
					q.push(b);
				}
			}
		}
		
		cout<<num<<endl;
	}
	return 0;
}