优先队列集锦(其实都是水题啦)

1 HDU-1873   水题,基本优先队列。 

#include <iostream>
#include<stdio.h>
#include<algorithm>
#include<string>
#include<queue>
using namespace std;
struct node
{
    int lev;
    int ord;
    bool friend operator < (const node a,const node b)
    {
       if(a.lev!=b.lev)return a.lev < b.lev;
       else return a.ord > b.ord;
    }
};
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        char s[5];
        priority_queue<node> doc[4];
        for(int i=1;i<=3;i++)
        {
            while(!doc[i].empty()) doc[i].pop();
        }
        int cnt=0;
        for(int i=1;i<=n;i++)
        {
            struct node now;
            scanf("%s",s);
            if(s[0]=='I')
            {
                int a,b;
                now.ord=++cnt;
                scanf("%d%d",&a,&b);
                now.lev=b; doc[a].push(now);
            }
            else
            {
                int a;
                scanf("%d",&a);
                if(!doc[a].empty())
                {
                    now=doc[a].top();
                    doc[a].pop();
                    printf("%d\n",now.ord);
                }
                else printf("EMPTY\n");
            }
        }
    }
    return 0;
}


2 POJ-1442

用两个优先队列,一个是K个从大到小(队列首就是第K小数字),另一个队里从小到大是保存其他的数字(队列顶是其他个最小的元素)

进行如下操作

A 如果第一个队列未满K个直接扔进去

B 如果满K个则每次直接扔到另一个队列,将另一个队列的队列首和第一个队列首比较,如果小的话,pop第一个队列,把第二个队列首放进去。

#include <iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
int num[30100];
int ord[30100];
int ans[30100];

int main()
{
    priority_queue<int,vector<int>,greater<int> > res;
    priority_queue<int> aim;

    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++) scanf("%d",&num[i]);
    for(int i=0;i<m;i++) scanf("%d",&ord[i]);
    int cnt=0;
    for(int i=0;i<m;i++)
    {
        int pos=i+1;
        int temp=ord[i];
        for(;cnt<temp;cnt++)
        {
            res.push(num[cnt]);
        }
        while(aim.size()<pos)
        {
            int a; a=res.top();res.pop();
            aim.push(a);
        }
        while(!res.empty()&&!aim.empty()&&res.top()<aim.top())
        {
            int a=res.top(),b=aim.top();
            res.pop(); aim.pop();
            aim.push(a); res.push(b);
        }
        ans[i]=aim.top();
    }
    for(int i=0;i<m;i++) printf("%d\n",ans[i]);
    return 0;
}

POJ 2312. 

BFS,因为每次拓展的结果不一定是最小的,如果这块有墙,那么从这个点出发进行拓展的答案有可能错误,所以需要优先拓展步数小的节点。

#include <iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<queue>
using namespace std;

char map[350][350];
bool vis[350][350];
int dir[4][2]={1,0 ,-1,0 ,0,1, 0,-1};
int n,m;
struct node
{
    int x,y;
    int step;
    bool friend operator < (const node a,const node b)
    {
        return a.step>b.step;
    }
};

bool jud(struct node a)
{
    if(a.x<1||a.y<1||a.x>n||a.y>m) return 0;
    return 1;
}

void bfs(int sx,int sy)
{
    struct node u,v;
    u.x=sx;u.y=sy;
    u.step=0;
    vis[sx][sy]=1;
    priority_queue<node> que;
    que.push(u);
    while(!que.empty())
    {
       u=que.top();
       que.pop();
       if(map[u.x][u.y]=='T')
       {
           printf("%d\n",u.step);
           return;
       }
       for(int i=0;i<4;i++)
       {
            v.x=u.x+dir[i][0];v.y=u.y+dir[i][1];
            if(jud(v)&&!vis[v.x][v.y]&&map[v.x][v.y]!='S'&&map[v.x][v.y]!='R')
            {
                vis[v.x][v.y]=1;
                v.step=u.step+1;
                if(map[v.x][v.y]=='B') v.step++;
                que.push(v);
            }
       }
    }
    printf("-1\n");
    return;
}


int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n==0||m==0) break;
        int sx,sy;
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                scanf(" %c",&map[i][j]);
                if(map[i][j]=='Y') {sx=i;sy=j;}
            }
        }
        bfs(sx,sy);
    }
    return 0;
}

HDU 4006

水题,上面讲过这种题,直接上代码了。

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;

int main()
{
    int n,k;
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        priority_queue<int ,vector<int>,greater<int> >que;
        while(!que.empty()) que.pop();
        int cnt=0;
        for(int i=0;i<n;i++)
        {
            char s[5];
            scanf("%s",s);
            if(s[0]=='I')
            {
                int a;
                scanf("%d",&a);
                if(cnt==k)
                {
                    if(que.top()<a)
                    {
                        que.pop(); que.push(a);
                    }
                    else continue;
                }
                else { que.push(a); cnt++;}
            }
            else
            {
                printf("%d\n",que.top());
            }

        }
    }
    return 0;
}

HDU 1509

水题

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
struct node
{
    char s[50];
    int date;
    int pro;
    int order;
    bool friend operator < (const node a, const node b)
    {
        if(a.pro!=b.pro) return a.pro > b.pro;
        else return a.order > b.order ;
    }
};
int main()
{
    priority_queue<node> que;
    char s[20];
    int cnt=0;
    while(scanf("%s",s)!=EOF)
    {
        if(s[0]=='P')
        {
            struct node t;
            scanf("%s%d%d",t.s,&t.date,&t.pro);
            t.order=cnt;
            cnt++;
            que.push(t);
        }
        else
        {
          if(!que.empty())
          {
              struct node t;
              t=que.top() ; que.pop();
              printf("%s %d\n",t.s,t.date);
          }
          else
          {
              printf("EMPTY QUEUE!\n");
          }
        }
    }
    return 0;
}

HDU1896

模拟一下就好。原来做过的题

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
struct node
{
    int pos;
    int trow;
    bool friend operator < (const node a,const node b)
    {
        if(a.pos!=b.pos) return a.pos>b.pos;
        else return a.trow>b.trow;
    }
};
int main()
{
    int T;
    scanf("%d",&T);
    for(int tt=0;tt<T;tt++)
    {
        int n;
        scanf("%d",&n);
        priority_queue<node> que;
        while(!que.empty()) que.pop();
        for(int i=0;i<n;i++)
        {
           struct node a;
           scanf("%d%d",&a.pos,&a.trow);
           que.push(a);
        }

        int ans=0,cnt=1;

        while(!que.empty())
        {
            if(cnt%2)
            {
               struct node x;
               x=que.top();
               x.pos+=x.trow;
               que.pop();
               que.push(x);
               ans=x.pos;
            }
            else
            {
                 ans=que.top().pos;
                 que.pop();
            }
            cnt++;
        }
        printf("%d\n",ans);
    }
    return 0;
}
HDU 1242

逆向BFS,从公主的位置出发去找最近的朋友即可

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
struct node
{
    int x,y,step;
    bool friend operator < (const node a,const node b)
    {
        return a.step > b.step;
    }
};

char  map[222][222];
bool vis[222][222];
int dir[4][2]={1,0 ,-1,0 ,0,1,0,-1};
int n,m,sx,sy;

bool j(struct node a)
{
    if(a.x<1||a.y<1||a.x>n||a.y>m) return 0;
    return 1;
}

void bfs(int sx,int sy)
{
    priority_queue<node> que;
    while(!que.empty()) que.pop();
    memset(vis,0,sizeof(vis));

    struct node u,v;
    u.x=sx; u.y=sy; u.step=0;
    vis[sx][sy]=1;
    que.push(u);
    while(!que.empty())
    {
      u=que.top();que.pop();
      if(map[u.x][u.y]=='r')
      {
          printf("%d\n",u.step);
          return;
      }
       for(int i=0;i<4;i++)
       {
          v.x=u.x+dir[i][0];
          v.y=u.y+dir[i][1];
          v.step=u.step+1;
          if(j(v)&&!vis[v.x][v.y]&&map[v.x][v.y]!='#')
          {
             vis[v.x][v.y]=1;
             if(map[v.x][v.y]=='x') v.step+=1;
             que.push(v);
          }
       }
    }
    printf("Poor ANGEL has to stay in the prison all his life.\n");
    return;
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            scanf(" %c",&map[i][j]);
            if(map[i][j]=='a') {sx=i;sy=j;}
        }
    }
    bfs(sx,sy);
    }
    return 0;
}

HDU4393

这道题刚开始一直wa,后来看了题解。直接开个speed100的优先队列(第一秒的速度优先),每次循环一遍找出最远的即可

#include <iostream>
#include<stdio.h>
#include<algorithm>
#include<queue>
#include<string.h>
using namespace std;
struct node
{
   int pos,ord;
   bool friend operator < (const node a,const node b)
   {
       if(a.pos!=b.pos ) return a.pos<b.pos;
       else return a.ord>b.ord;
   }
};

int ans[50020];
priority_queue<node> a[105];
int main()
{
    int T;
    scanf("%d",&T);
    for(int tt=1;tt<=T;tt++)
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            struct node x;
            int sp;
            scanf("%d%d",&x.pos,&sp);
            x.ord=i;
            a[sp].push(x);
        }
        for(int i=0;i<n;i++)
        {
            int ma=0,pos=50001,kpos=0;
            for(int j=1;j<=100;j++)
            {
               if(a[j].empty()) continue;
               else
               {
                  if( i*j+a[j].top().pos>ma||(i*j+a[j].top().pos==ma&&pos>a[j].top().ord))
                  {
                       ma= i*j+a[j].top().pos ; pos=a[j].top().ord;kpos=j;
                  }
               }
            }
            a[kpos].pop();
            ans[i]=pos;
        }
        printf("Case #%d:\n",tt);
        printf("%d",ans[0]);
        for(int i=1;i<n;i++)
        {
            printf(" %d",ans[i]);
        }
        printf("\n");
    }
    return 0;
}

POJ 2431 思路和上面的一模一样

#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
priority_queue<int> que[102];
int n;
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=0;i<=100;i++)
        {
            while(!que[i].empty()) que[i].pop();
        }
        for(int i=0;i<n;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            que[b].push(a);
        }
        int dis,ful;
        scanf("%d%d",&dis,&ful);
        dis-=ful;ful=0;
        int ans=0;
        while(1)
        {
            if(dis<=0) break;
            int pos=-1;
            for(int i=100;i>0;i--)
            {
                if(que[i].empty()) continue;
                if(que[i].top()>=dis) {pos=i;break;}
            }
            if(pos<0) break;
            else
            {
                ans++;
                dis-=pos;
                que[pos].pop();
            }
        }
        if(dis<=0)
        {
            printf("%d\n",ans);
        }
        else printf("%d\n",-1);
    }
    return 0;
}

POJ2970

自己是用 第一优先级截止日期,第二优先级bi/ai(大到小) 第三优先级bi 来做的,优先填满最贵的。结果错了 。因为有可能两个较便宜的比一个贵的还贵

然后看了网上的思路

很明显,如果手头这个工作无法完成,那么我们就需要在已经完成的工作中(这里其实包括手头的工作)找到那个a最大的工作,然后给钱来减少那个工作所需的时间,以便以最小的花销来完成现在所有的工作。所以我们需要一个优先队列来维护当前拥有最大a的那个工作。我们可以直接调用stl里的priority_queue来完成这个工作,每次取出a最大的工作,如果这项工作已经不能再给钱了,那么就将其POP出队列,选取下一个,直到我们可以再deadline前完成手头的工作。

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
struct node
{
    int di,ai,bi,rest;
    double val;
    bool friend operator < (const node a,const node b)
    {
        return a.ai<b.ai;
    }
}test[101000];

bool cmp (const node a,const node b )
{
    return a.di < b.di;
}

priority_queue<node> que;
int n;
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        while(!que.empty()) que.pop();
        for(int i=0;i<n;i++)
        {
            scanf("%d%d%d",&test[i].ai,&test[i].bi,&test[i].di);
            test[i].val=1.00000*test[i].bi;
            test[i].val=test[i].val/test[i].ai;
            test[i].rest=test[i].bi;
        }
        sort(test,test+n,cmp);
        int time=0;
        double ans=0;
        for(int i=0;i<n;i++)
        {
            que.push(test[i]);
            time+=test[i].bi;
            if(time<=test[i].di) continue;
            else
            {
                while(1)
                {
                    if(time<=test[i].di) break;
                    struct node a;
                    a=que.top(); que.pop();
                    int need=time-test[i].di;
                    if(need>=a.rest)
                    {
                      double temp=a.rest*1.000000;
                      temp/=(1.000000*a.ai);
                      ans+=temp; time-=a.rest; continue;
                    }
                    else
                    {
                        a.rest-=need;
                        double temp=need*1.000000;
                        temp/=(1.0000000*a.ai);
                        ans+=temp; time=test[i].di;
                        que.push(a);
                        break;
                    }
                }
            }
        }
        printf("%.2f\n",ans);
    }
    return 0;
}

总的来说这两天做的优先队列,质量都不高,以练手为主吧。(其实是因为太忙了,没时间想难题。。。。。)

 










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值