传送门

 

•题意

  二维平面上有 )$;

  平面上的每个整点坐标上都可以放置一枚硬币,但是要求任意两枚硬币的横坐标不相同;

  问最多有多少条线段可以放置硬币。

•题解1

  考虑到当 $X=x$ 时,最多有一条线段可以放置一枚硬币;

  那么,我们可以从左到右查找最多有多少条线段可以放置硬币;

  定义变量 $X$ 表示 $[0,X]$ 位置已放置好硬币;

  既然是按照 $x$ 来的,那么我们就需要将所有可能可以放置硬币的线段按照 $l$ 升序排列,如果 $l$ 相同,按照 $r$ 升序排列;

  考虑用优先级队列,首先将所有线段放入优先级队列 $q$ 中,并定义 $X=0$;

  每次选择从 $q$ 的队头取出 $l$ 小的线段,判断这条线段的 $l'$ 与 $X$ 的位置关系:

    ①如果 $l' \leq X$,说明当前这条线段的 $[l',X]$ 位置 不能放置硬币,只能考虑 $[X+1,r']$ 位置是否还可以放置硬币;

       那么,此时,我们就将 $[X+1,r_i]$ 丢到 $q$ 中,代表可能从 $[X+1,r']$ 中选择某位置放置硬币;

    ②如果 $l' > X$,说明 $[X,l')$ 间无可放置硬币的线段,那么我们要选择一枚硬币放置在 $l'$ 处,即当前这条线段上,并更新 $X=l'$;

•Code

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+50;
 4 
 5 int n;
 6 struct Heap
 7 {
 8     int l,r;
 9     bool operator < (const Heap &obj)const
10     {
11         if(l != obj.l)
12             return l > obj.l;
13         return r > obj.r;
14     }
15 };
16 priority_queue<Heap >q;
17 
18 int Solve()
19 {
20     int X=0;
21     int ans=0;
22     while(!q.empty())
23     {
24         Heap tmp=q.top();
25         q.pop();
26 
27         /**
28             如果 tmp.l <= X,那么[tmp.l,X]是已求出最解的位置
29             但是[X+1,tmp.r] 还是没有放置硬币的
30             所以当前线段还是有可能在[X+1,tmp.rr]区间放置一枚硬币的
31             所以将其加入到q中
32         */ 
33         if(tmp.l <= X && X+1 <= tmp.r)
34             q.push({X+1,tmp.r});
35         else if(tmp.l > X)///如果tmp.l > X,更新ans,X
36         {
37             ans++;
38             X=tmp.l;
39         }
40     }
41     return ans;
42 }
43 int main()
44 {
45     int T;
46     scanf("%d",&T);
47     while(T--)
48     {
49         while(!q.empty())
50             q.pop();
51 
52         scanf("%d",&n);
53         for(int i=1;i <= n;++i)
54         {
55             int l,r;
56             scanf("%d%d",&l,&r);
57             q.push({l,r});
58         }
59         printf("%d\n",Solve());
60     }
61     return 0;
62 }
View Code

相关文章: