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