優先佇列集錦(其實都是水題啦)
阿新 • • 發佈:2019-01-22
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;
}
總的來說這兩天做的優先佇列,質量都不高,以練手為主吧。(其實是因為太忙了,沒時間想難題。。。。。)