poj 3481 set 容器 银行 K P

题意:输入1的时候 输入 K  P,输入2的时候找出最大的P对应的K,并删除这个P。输入3的时候找出最小的P对应的K,并删除P。输入2,3的时候如果没有P了,那么输出0.

思路:利用set 和 priority_queue

#include<iostream>
#include<set>
using namespace std;
typedef struct 
{
  int k,p;
}settype;
bool operator < (const settype &a,const settype &b)
{return a.p<b.p;}//因为STL中默认是以小于号来排序的,所以要重载小于号,如果a.p>b.p那么默认是以递减的顺序排的。
int main()
{
  set<settype> Q;
  set<settype>::iterator iter;
  settype S;
  int a;
  while(scanf("%d",&a)!=EOF&&a)
  {
    if(a==0) break;
    else if(a==1)
    {
      scanf("%d%d",&S.k,&S.p);
      Q.insert(S);
    }
    else if(a==2)
    {
      if(!Q.empty())
      {
        iter=Q.end();//end返回的是最后一个元素的后面的位置,迭代器的值。
        iter--;
        S=*iter;
        cout<<S.k<<endl;
        Q.erase(*iter);
      }
      else cout<<"0"<<endl;
    }
    else if(a==3)
    {
      if(!Q.empty())
      {
        iter=Q.begin();
        cout<<(*iter).k<<endl;
        Q.erase(*iter);
      }
      else cout<<"0"<<endl;
    }
  }
}

下面是用数组对应的K,但是内存开销相当大。

#include<iostream>
#include<set>
using namespace std;
int a[10000010];
int main()
{
  set<int> Q;
  set<int>::iterator iter;
  int t,p,k;
  while(scanf("%d",&t)!=EOF&&t)
  {
    if(t==1)
    {
      scanf("%d%d",&k,&p);
      a[p]=k;
      Q.insert(p);
    }
    else if(t==2)
    {
      if(!Q.empty())
      {
        iter=Q.end();
        iter--;
        p=*iter;
        cout<<a[p]<<endl;
        Q.erase(p);
      }
      else cout<<"0"<<endl;
    }
    else if(t==3)
    {
      if(!Q.empty())
      {
        iter=Q.begin();
        p=*iter;
        cout<<a[p]<<endl;
        Q.erase(p);
      }
      else cout<<"0"<<endl;
    }
  }
}

这个是用的优先队列,貌似时间比前两个快啊

#include<iostream>
#include<vector>
#include<queue>
using namespace std;
long a[10000010];
int main()
{
  long K,P;
  priority_queue<long,vector<long>,greater<int> > L;
  priority_queue<long,vector<long>,less<long> > H;
  long t;
  while(scanf("%ld",&t)!=EOF&&t)
  {
    if(t==1)
    {
      scanf("%ld %ld",&K,&P);
      a[P]=K;
      L.push(P);
      H.push(P);
      //system("pause");
    }
    else if(t==2)
    {
      if(!H.empty())
      {
        P=H.top();
        while(!H.empty()&&a[P]==-1)
        {
          H.pop();
          P=H.top();
        }
        if(!H.empty())
        {
          P=H.top();
          cout<<a[P]<<endl;
          a[P]=-1;
        }
        else cout<<"0"<<endl;
      }
      else cout<<"0"<<endl;
    }
    else if(t==3)
    {
      if(!L.empty())
      {
        P=L.top();
        while(!L.empty()&&a[P]==-1)
        {
          L.pop();
          P=L.top();
        }
        if(!L.empty())
        {
          P=L.top();
          cout<<a[P]<<endl;
          a[P]=-1;
        }
        else cout<<"0"<<endl;
      }
      else
      cout<<"0"<<endl;
    }
  }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值