• Expedition---poj2431(优先队列-堆的实现)


    题目链接:http://poj.org/problem?id=2431

    题意:一辆卡车需要行驶 L 距离,车上油的含量为 P,在行驶的过程中有 n 个加油站 每个加油站到终点的距离是ai,每个加油站最多给卡车加 b 单位的油;求最后到达终点需要加油的最少次数;如果不能到达,输出-1;

    我们可以从起点开始算,看每次油箱中的油是否能够到达下一个加油站,如果不能就加上已经经过的加油站的所能加的最大加油量,如果能到达,就记录一下此加油站可以被加进去;因为我们每次都需要加进去最大的加油

    量,所以我们可以用优先队列;来存,那么每次取出来的就是最大值;

    时间复杂度是O(n*logn)

    用c++中的STL:

    #include<stdio.h>
    #include<stdio.h>
    #include<string.h>
    #include<queue>
    #include<algorithm>
    #define N 101000
    #define INF 0xfffffff
    using namespace std;
    
    int n, P, L, ans, f;
    
    struct node
    {
        int a,b;
    } s[N];
    
    int cmp(node n1,node n2)
    {
        return n1.a<n2.a;
    }
    
    void slove()
    {
        priority_queue<int> Q;///优先队列;
    
        int pos = 0, i = 0;///pos表示当前所在位置;
    
        while(i <= n)
        {
            int d = s[i].a - pos;
    
            while(Q.size() && P < d)///当不能到达下一个加油站时,要取出最大的加油量加进去;
            {
                int p = Q.top(); Q.pop();
                P += p;
                ans ++;
            }
            if(P >= d)
            {
                Q.push(s[i].b);
                pos = s[i].a;
                P -= d;
            }
            else
            {
                ans = -1;
                return ;
            }
            i ++;
        }
    }
    
    int main()
    {
        int i;
    
        while(scanf("%d",&n) != EOF)
        {
            memset(s, 0, sizeof(s));
    
            ans=0;
    
            for(i=0; i<n; i++)
                scanf("%d %d",&s[i].a, &s[i].b);
    
            scanf("%d %d", &L, &P);
    
            for(i=0; i<n; i++)
                s[i].a = L - s[i].a;
    
            s[i].a = L;
            s[i].b = 0;///把终点当成最后一个加油站处理;
    
            sort(s, s+n+1, cmp);
    
            slove();
    
            printf("%d
    ", ans);
        }
        return 0;
    }
    View Code

    手写实现堆---优先队列;

    #include<stdio.h>
    #include<stdio.h>
    #include<string.h>
    #include<queue>
    #include<algorithm>
    #define N 11000
    #define INF 0x3f3f3f3f
    using namespace std;
    
    
    int Max_Heap[N], K;///K代表Max_Heap的个数;
    int p;
    
    void Push(int x)///在最大堆中插入x;
    {
        Max_Heap[K++] = x;///放到最后一个节点处;
    
        int t = K-1;
    
        while(Max_Heap[t] > Max_Heap[t/2] )///当它的值大于它的父节点的值时,要交换一下位置;
        {
            swap(Max_Heap[t], Max_Heap[t/2]);
            t = t/2;
        }
    }
    void Pop()
    {
        K --;///删除元素,堆中总个数减一;
        
        Max_Heap[1] = Max_Heap[K];///把最后一个数放到最上面,然后一步一步往下更新堆;
    
        Max_Heap[K] = -1;///防止越界,相当于建立哨兵;
    
        int t = 1;///从第一个节点开始往下更新;
    
        while( Max_Heap[t] < Max_Heap[t*2] || Max_Heap[t] < Max_Heap[t*2+1])
        {
            if(Max_Heap[t] < Max_Heap[t*2] && Max_Heap[t*2] > Max_Heap[t*2+1])
            {///左儿子大于它时,并且满足左儿子大于右儿子,让左儿子上去;
                swap(Max_Heap[t], Max_Heap[t*2]);
                t = t*2;
            }
            else
            {
                swap(Max_Heap[t], Max_Heap[t*2+1]);
                t = t*2 + 1;
            }
        }
    }
    
    
    int n, P, L, ans, f;
    
    struct node
    {
        int a,b;
    } s[N];
    
    int cmp(node n1,node n2)
    {
        return n1.a<n2.a;
    }
    
    void slove()
    {
        memset(Max_Heap, -1, sizeof(Max_Heap));
    
        Max_Heap[0] = INF;
    
        K = 1;
    
        int pos = 0, i = 0;
    
        while(i <= n)
        {
            int d = s[i].a - pos;
    
            while(K!=1 && P < d)
            {
                int p = Max_Heap[1];
                Pop();
                P += p;
                ans ++;
            }
            if(P >= d)
            {
                Push(s[i].b);
                pos = s[i].a;
                P -= d;
            }
            else
            {
                ans = -1;
                return ;
            }
            i ++;
        }
    }
    
    int main()
    {
        int i;
    
        while(scanf("%d",&n) != EOF)
        {
            memset(s, 0, sizeof(s));
    
            ans=0;
    
            for(i=0; i<n; i++)
                scanf("%d %d",&s[i].a, &s[i].b);
    
            scanf("%d %d", &L, &P);
    
            for(i=0; i<n; i++)
                s[i].a = L - s[i].a;
    
            s[i].a = L;
            s[i].b = 0;
    
            sort(s, s+n+1, cmp);
    
            slove();
    
            printf("%d
    ", ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    rapidjson 的练习
    在Struts2中集成Spring详细讲解
    AJAX实例入门
    Redhat Enterprise Linux中如何关闭SELinux?
    C3P0连接池详细配置
    hibernate中load,get;find,iterator;merge,saveOrUpdate,lock的区别
    107个常用Javascript语句
    车祸 shit
    JAVASCRIPT实现XML分页
    javabeans的运用
  • 原文地址:https://www.cnblogs.com/zhengguiping--9876/p/5373855.html
Copyright © 2020-2023  润新知