• 2015 多校联赛 ——HDU5360(贪心+优先队列)


    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

    找出能约出最多人的顺序。  假设前面已经有x人同意了,对于第i个人而言, l[i] <= x <= r[i] ,则第i个人同意。求以怎样的顺序去找人最合适。


    感觉思路大致方向是对的,只是方法上有些问题,不够简便(- -)

    在同l都满足的情况下,选择的r要尽可能的小,才能保证后面选的更多

    scanf("%d",&tmp);  

    q[p[i]].push_back(node(tmp,i));


    p[i]是它的左边,tmp是右边,用这样保存的话在查找的时候便不用查找全部。(详细看代码)

    每次查找后都保证了(l[i] <= i 的全部被包括了,感觉别人好机智 。。)


    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <queue>
    #include <algorithm>
    #pragma comment(linker, "/STACK:102400000,102400000")
    using namespace std;
    
    struct node
    {
        int b, num;
        node() {}
        node( int _b, int _num )
        {
            b = _b, num = _num;
        }
        bool operator < ( const node & l ) const
        {
            return b > l.b;
        }
    };
    int p[100010];
    int n;
    int rec[100010];
    int vis[100010];
    int aim;
    vector<node>q[100010];
    priority_queue<node>que;
    
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            aim=0;
            memset(vis,0,sizeof(vis));
            scanf("%d",&n);
            for(int i = 0;i <= n;i++)
                q[i].clear();
    
            for(int i=1; i<=n; i++)
            {
                scanf("%d",&p[i]);
            }
            
            for(int i=1; i<=n; i++)            
            {
                int tmp;
                scanf("%d",&tmp);
                q[p[i]].push_back(node(tmp,i));           //用左边界来记录
            }
    
            while(1)
            {
                int flag = 0;
                for(int i=0; i < q[aim].size(); i++)      //这里就不需要全部找一遍
                {
                        que.push(q[aim][i]);
                }
                while(!que.empty())
                {
                    if(que.top().b>= aim && vis[que.top().num]!=1)
                    {
                        vis[que.top().num]=1;
                        rec[aim] = que.top().num;
                        aim++;
                        que.pop();
                        flag = 1;
                        break;
                    }
                    que.pop();
                }
                if(!flag)
                    break;
            }
    
            printf("%d
    ",aim);
            if(aim)
            {
                printf("%d",rec[0]);
                for(int i=1; i<aim; i++)
                    printf(" %d",rec[i]);
    
                for(int i=1; i<=n; i++)
                {
                    if(vis[i]==0)
                        printf(" %d",i);
                }
            }
            else
            {
                printf("1");
                for(int i = 2; i <= n; i++)
                    printf(" %d",i);
            }
            printf("
    ");
        }
        return 0;
    }
    

      

  • 相关阅读:
    如何在SQLite中创建自增字段?
    Windows XP平台下编译boost[1.47及以上]
    智能指针的向下转型
    采用Boost::filesystem操作文件
    CodeSmith访问数据库
    std::string的一些操作
    PDF加入内嵌字体
    悟空和唐僧的对话
    收获和教训的一天配置ds1401
    vxworks的一个changlog
  • 原文地址:https://www.cnblogs.com/Przz/p/5409796.html
Copyright © 2020-2023  润新知