HDU5360——优先队列——Hiking

Problem Description

There are n soda conveniently labeled by 1,2,…,n. beta, their best friends, wants to invite some soda to go hiking. The i-th soda will go hiking if the total number of soda that go hiking except him is no less than li and no larger than ri. beta will follow the rules below to invite soda one by one:
1. he selects a soda not invited before;
2. he tells soda the number of soda who agree to go hiking by now;
3. soda will agree or disagree according to the number he hears.

Note: beta will always tell the truth and soda will agree if and only if the number he hears is no less than li and no larger than ri, otherwise he will disagree. Once soda agrees to go hiking he will not regret even if the final total number fails to meet some soda‘s will.

Help beta design an invitation order that the number of soda who agree to go hiking is maximum.

Input

There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

The first contains an integer n (1≤n≤105), the number of soda. The second line constains n integers l1,l2,…,ln. The third line constains n integers r1,r2,…,rn. (0≤li≤ri≤n)
It is guaranteed that the total number of soda in the input doesn‘t exceed 1000000. The number of test cases in the input doesn‘t exceed 600.

Output

For each test case, output the maximum number of soda. Then in the second line output a permutation of 1,2,…,n denoting the invitation order. If there are multiple solutions, print any of them.

Sample Input

4
8
4 1 3 2 2 1 0 3
5 3 6 4 2 1 7 6
8
3 3 2 0 5 0 3 6
4 5 2 7 7 6 7 6
8
2 2 3 3 3 0 0 2
7 4 3 6 3 2 2 5
8
5 6 5 3 3 1 2 4
6 7 7 6 5 4 3 5

Sample Output

7
1 7 6 5 2 4 3 8
8
4 6 3 1 2 5 8 7
7
3 6 7 1 5 2 8 4
0
1 2 3 4 5 6 7 8

Source

2015 Multi-University Training Contest 6

/*
大意:n个人参加一个活动的条件有人数限制,l和r,问你最多有多少个人能一起去,把不能参加的人随便输出
用优先队列维护满足的情况
把块从0分到n,贪心地把r最小的并且满足大于等于l的值取出,注意判断如果这一次没有了,下一次也肯定没有这种情况
*/
/************************************************
Author        :powatr
Created Time  :2015-8-6 14:45:47
File Name     :b.cpp
 ************************************************/

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std;

#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int MAX = 1e5 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
struct edge{
    int l, r, id;
}a[MAX];
struct edge1{
    int x, y;
};
edge1 P;

struct cmp1
{
    bool operator () (edge1 x, edge1 y)
    {
        return x.x > y.x;
    }
};

int b[MAX];
int vis[MAX];
int n;
vector<edge1>G[MAX];

int main(){
    int T;
    priority_queue < edge1 , vector<edge1> , cmp1 > q;
    scanf("%d", &T);
    while(T--){
        memset(vis, 0, sizeof(vis));
        scanf("%d", &n);
        memset(a, 0, sizeof(a));
        for(int i = 1; i <= n; i++){
            scanf("%d",&a[i].l);
        }
        for(int i = 0 ; i <= 100000; i++)
            G[i].clear();
        for(int i = 1; i <= n; i++)
            scanf("%d",&a[i].r);
        for(int i = 1; i <= n; i++)
            a[i].id = i;
        // sort(a + 1, a + n + 1);

         while(!q.empty()) q.pop();

        for(int i = 1; i <= n; i++)
            G[a[i].l].push_back((edge1){a[i].r, a[i].id});

        for(int i = 0 ; i < G[0].size(); i++)
            q.push((edge1){G[0][i].x,G[0][i].y});
        int ans = 1;
        edge1 m;
        if(!q.empty()){
            m = q.top();
         if(m.x >= 0){
           b[ans++] = m.y;
            q.pop();
         }
        }

        for(int i = 1; i <= n; i++){

            for(int j = 0; j < G[i].size(); j++)
                q.push((edge1){G[i][j].x, G[i][j].y});
           // if(ans < i + 2) break;
            while(!q.empty()){
                m = q.top();
               if(ans < i + 1) break;
               if(ans == i + 2) break;
                if(m.x >= i){
                q.pop();
                b[ans++] = m.y;
            }
                else q.pop();
            }
        }
        printf("%d\n", ans - 1);
        for(int i = 1; i < ans ; i++){
            printf("%d ", b[i]);
            vis[b[i]] = 1;
        }
         for(int i = 1 ; i <= n; i++)
             if(!vis[i])
                    printf("%d ", i);
         puts("");
    }
    return 0;
}

  

时间: 2024-10-08 06:53:03

HDU5360——优先队列——Hiking的相关文章

hdu5360 Hiking(水题)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Hiking Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 724    Accepted Submission(s): 384Special Judge Problem Description There are 

hdu 5360 Hiking(优先队列+贪心)

题目:http://acm.hdu.edu.cn/showproblem.php? pid=5360 题意:beta有n个朋友,beta要邀请他的朋友go hiking,已知每一个朋友的理想人数[L,R](现有L~R个人准备去,那么这个朋友就去). 求最多有多少人去. 及beta邀请朋友的顺序. 分析:每次邀请人的最优解就是:选会去的人里面R最小的那个人. 代码实现的话,cur代表已经准备go hiking的人数,每次将全部L<=cur的人放进优先队列,选出R最小的那个. 假设队列为空,那么剩下

HDU 5360——Hiking——————【贪心+优先队列】

Hiking Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 118    Accepted Submission(s): 69Special Judge Problem Description There are n soda conveniently labeled by 1,2,…,n. beta, their best fri

HDU 5360 Hiking (贪心+优先队列)

本文纯属原创,转载注明出处:http://blog.csdn.net/zip_fan.谢谢. 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=5360 Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Special Judge Problem Description There are n soda conveniently la

HDU5360 Hiking

1.题目描述:点击打开链接 2.解题思路:本题利用优先队列解决,然而在这次多校的比赛时候并没有往这个角度考虑,最终要么WA要么TLE==.其实本题的贪心策略很好想:如果把题目中的人数看做数轴上的点的话,那么应该按照从0依次递增的顺序来选择区间,把符合条件的区间预先存起来,然后按照他们的终点由小到大排序,第一个就是我们要的区间,如果遇到第一个区间的终点也小于当前值,那么也将他放入ans数组,只不过被邀请的人数不变而已.显然,看到这种思路就应当往优先队列的角度考虑.这里应当首先对区间按照起点大小排序

HDU 5360 Hiking(优先队列)

Hiking Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 492    Accepted Submission(s): 263 Special Judge Problem Description There are  soda conveniently labeled by . beta, their best friends,

HDU 5360(2015多校6)-Hiking(优先队列)

题目地址:HDU 5360 题意:给定n个人,现在要邀请这些人去远足,但每个人同意邀请的条件是当前已经同意去远足的人数c必须满足c>=l[i]&&c<=ri,问你邀请的顺序是什么才能使尽可能多的人去远足,若有多个最优解,输出任意的一个. 思路:先按照L从小到到排序,把当前符合的L放入优先队列中 ,然后对队列中的R从小到大排序,贪心的选择R小的,然后乱搞一番就可以了. #include <stdio.h> #include <math.h> #includ

HDU5630 Hiking(贪心+优先队列)

题目链接:传送门 题意: 邀请n个人去参加聚会,对于第i个人只有当去人数大于等于li,小于等于ri的时候这个人才会去参加聚会, 让你确定一个邀请的顺序,使得最后去参加聚会的人数最多. 分析: 读完题目后就感觉这个题是个贪心,但是没有想好怎么去维护,比赛完了看完题解感觉太水了... 首先肯定是要按照l对所有的数进行排序,比如说我们当前已经有tot个人确定参加了,那么剩下的我们 还要贪心的进行选择.选择满足l<=tot&&r>=tot中的r最小的那个人,很明显,只有这样选择对后来人

HDOJ 5360 Hiking 优先队列+贪心

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=5360 题意: 大概的意思就是每个人有个人数接受范围$[l_i,r_i]$,现在你每次能从还未被选取的人中选择一个人,如果当前人数符合这个人的需求,那么这个人就会被选中.现在让你输出一个选择的序列,使得被选择的人数尽量多. 题解: 就贪心就好,总的来说就是人数不断增大的时候,每次从可行的所有$l$中选择$r$最小的那个.至于为什么这样是最优的..需要脑补. 代码: #include<iostream>