【优先队列】【最近连STL都写不出来了/(ㄒoㄒ)/~~】hdu_5360/多校#6_1008

题意:就是让你写出一个邀请朋友的顺序,朋友答应一起出去玩的条件是除他以外所有同意出去玩的人数要在[ l[i], r[i] ]范围内,否则他就不答应。

分析:这题比赛的时候想麻烦了,其实只要在左边界满足的条件下看右边界就可以。

     首先将左边界满足的所有右边界及其id加到一个按右边界值从小到大排序的优先队列里,然后取第一个右边界,如果右边界值小于当前所有同意出去玩的人数,直接将其pop()掉,继续看队列里的第一个元素,否则将此id保存下来,总人数+1,pop()掉第一个元素,继续添加左边界满足条件的右边界及id值。

Tips:  ①优先队列"priority_queue<int> pq;"是一个越小的整数优先级越低的优先队列。

    若想越小的整数优先级越高,则可以这样定义:"priority_queue<int,vector<int>, greater<int> > pq;"

     ②对于将右边界与id值插入到优先队列我们可以利用"pair<first, second>"来实现,"pair<first, second>"中默认的比较运算符为先比较first再比较second;

    同样要想让优先队列中右边界小的优先级越高,则可以"priority_queue<pii,vector<pii>, greater<pii> > pq;";

        标程里有更巧妙的就是直接取右边界值的相反数,这样就可以直接定义"priority_queue<pii> pq;"了;

     ③比较坑的一点用"priority_queue<pii,vector<pii>, greater<pii> > pq;"定义的时候在hdu上用C++交会返回编译错误,G++就会过;这两个的区别还是搞不懂。欢迎各路大神解惑。

附标程

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <queue>
 5 #include <algorithm>
 6 using namespace std;
 7 typedef pair<int, int> PII;
 8 const int MAXN = 100000 + 10;
 9 
10 struct W
11 {
12     int l, r, id;
13     bool operator < (const W &rhs) const
14     {
15         return l < rhs.l || (l == rhs.l && r < rhs.r);
16     }
17 } A[MAXN];
18 
19 int ret[MAXN], vs[MAXN], n;
20 
21 int main()
22 {
23     int T;
24     scanf("%d", &T);
25     for (int _ = 0; _ < T; ++ _)
26     {
27         scanf("%d", &n);
28         for (int i = 0; i < n; ++ i)
29         {
30             scanf("%d", &A[i].l);
31             A[i].id = i;
32             vs[i] = 0;
33         }
34         for (int i = 0; i < n; ++ i)
35         {
36             scanf("%d", &A[i].r);
37         }
38         sort(A, A + n);
39         priority_queue<PII> Q;
40         int cnt(0), i(0);
41         while (1)
42         {
43             while (i < n && A[i].l <= cnt) Q.push(PII(-A[i].r, A[i].id)), ++ i;
44             while (!Q.empty() && -Q.top().first < cnt) Q.pop();
45             if (Q.empty()) break;
46             ret[cnt ++] = Q.top().second;
47             Q.pop();
48             vs[ret[cnt - 1]] = 1;
49         }
50         printf("%d
", cnt);
51         for (int i = 0; i < n; ++ i) if (!vs[i]) ret[cnt ++] = i;
52         for (int i = 0; i < n; ++ i)
53         {
54             printf("%d%c", ret[i] + 1, " 
"[i == n - 1]);
55         }
56     }
57     return 0;
58 }
View Code

附G++ AC代码

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<queue>
 7 using namespace std;
 8 const int maxn = 100005;
 9 typedef pair<int, int> pii;
10 struct Node
11 {
12     int id, l, r;
13     Node () {}
14     Node (int _id, int _r) : id(_id), r(_r) {}
15     bool operator < (const Node& rhs) const
16     {
17         return l < rhs.l || (l == rhs.l && r < rhs.r);
18     }
19 }a[maxn];
20 int vis[maxn], id[maxn];
21 int main()
22 {
23     int T;
24     scanf("%d", &T);
25     while(T--)
26     {
27         int n; scanf("%d", &n);
28         for(int i = 0; i < n; i++) scanf("%d", &a[i].l), a[i].id = i, vis[i] = 0;
29         for(int i = 0; i < n; i++) scanf("%d", &a[i].r);
30         sort(a, a+n);
31         priority_queue<pii, vector<pii>, greater<pii> > pq;
32         int cur = 0, cnt = 0;
33         while(1)
34         {
35             while(cur < n && a[cur].l <= cnt)
36                 pq.push(pii(a[cur].r, a[cur].id)), cur++;
37 
38             while(!pq.empty() && cnt > (pq.top()).first)
39                 pq.pop();
40 
41             if(!pq.empty())
42             {
43                 vis[pq.top().second] = 1;
44                 id[cnt++] = pq.top().second;
45                 pq.pop();
46             }
47             else break;
48         }
49         printf("%d
", cnt);
50         for(int i = 0; i < n; i++)
51             if(!vis[i])
52                 id[cnt++] = i;
53         for(int i = 0; i < cnt; i++)
54         {
55             if(i) printf(" ");
56             printf("%d", id[i]+1);
57         }
58         printf("
");
59     }
60     return 0;
61 }
View Code
原文地址:https://www.cnblogs.com/LLGemini/p/4709945.html