题意:给定n个区间,第i个区间为[li,ri],它代表的坐标为(li,i),(li+1,i),(li+2,i)……(ri,i)。问最多有多少个坐标,它们的横坐标各不相同。
思路:将这些区间放入优先队列中,按照区间的左端点从小到大排序,如果左区间相同,按照右区间从小到大排序。mmax记录当前位置之前的最大左区间值,如果当前左区间的值大于mmax,答案加一,mmax更新;如果当前左区间的值小于mmax(代表当前横坐标与之前重合),将当前左区间值+1入队列。
代码:
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <sstream>
#include <cstdio>
#include <vector>
#include <string>
#include <cmath>
#include <stack>
#include <queue>
#include <map>
#include <set>
#define MAX 0x3f3f3f3f
#define fori(a,b) for(int i=a;i<=b;i++)
#define forj(a,b) for(int j=a;j<=b;j++)
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const double PI = acos(-1);
const int M=1e2+10;
struct node
{
int st,en;
}s;
bool operator <(node a,node b)
{
if(a.st!=b.st)
return a.st>b.st;
return a.en>b.en;
}
priority_queue<node>q;
int main()
{
//freopen("//home//acm//桌面//in","r",stdin);
int t;
scanf("%d",&t);
while(t--){
int n,st,en;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&s.st,&s.en);
q.push(s);
}
int mmax=0;
int ans=0;
while(!q.empty()){
node now=q.top();
q.pop();
if(now.st<=mmax&&now.st+1<=now.en){
now.st++;
q.push(now);
}
else if(now.st>mmax){
ans++;
mmax=now.st;
}
}
printf("%d\n",ans);
}
return 0;
}