题目链接
大致题意:
在一个平面上给你
n
n
n 条线段的左右端点的横坐标(可重叠),纵坐标为当前是第几条,即两点坐标为
(
l
,
i
)
(l,i)
(l,i) 和
(
r
,
i
)
(r,i)
(r,i) ,你可以在平面的任意整数坐标位置放置一个标记,标记的横坐标不可相同.问最给定的线段最多会被标记多少条。
解题报告:
贪心 ,对于某位置
x
x
x 的标记,我们肯定会左端点小于等于
x
x
x 且右端点大于等于
x
x
x,满足这样的线段可能有很多条,根据贪心性质肯定优先选择右端点较小的(优先队列维护),这样做能让右端点较大的在更右位置获得标记的可能性。
代码展示:
#include<bits/stdc++.h>
#define LL long long
#define pii pair<int,int>
#define all(x) x.begin(),x.end()
#define wp(x) write(x),putchar('\n')
#define wpl(x) write(x),putchar(' ')
#define mem(a, b) memset(a,b,sizeof(a))
using namespace std;
const int maxn = 3e5 + 5;
const int MOD = 998244353;
inline int read() {
int s = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
while (ch >= '0' && ch <= '9') {s = (s << 1) + (s << 3) + ch - '0'; ch = getchar();}
return s * f;
}
inline void write(int x) {
if (x < 0) x = -x, putchar('-');
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
}
struct node{
int x,y;
node(){}
node (int _x,int _y){
x=_x;y=_y;
}
bool operator < (const node &ls) const {
if(ls.x==x) return ls.y<y;
return ls.x<x;
}
};
priority_queue<node>q;
int main() {
int T=read(),n,x,y;
while(T--){
n=read();
for(int i=1;i<=n;i++){
x=read();y=read();
q.push(node(x,y));
}
int ans=0,st=0;
node pp;
while(!q.empty()){
pp=q.top();q.pop();
if(st<=pp.y){
ans++;
if(st<pp.x) st=pp.x+1;
else st++;
}
// 更新与之前左端点相同的点 令其 +1
while(!q.empty()&&q.top().x==pp.x){
node tt=q.top();q.pop();
tt.x++;
if(tt.x<=tt.y) q.push(tt);
}
}
wp(ans);
}
return 0;
}