感谢《啊哈!算法》的讲解,水鸟弄懂了什么是优先队列。
题意是:在路上有很多石子,给出他们的初始位置和小明能够将他们扔出的距离,当小明遇到奇数个石子的时候就会把它扔出,遇到偶数个就会忽略他,一直走到路上没有石子为止,求解最后一个石子的位置。
一开始用排序做的,果断超时,看了题解才知道这是优先队列。
贴优先队列的代码:
#include<stdio.h> int n; struct st { int pos,dis; }; st stone[100010]; void swap(int a,int b) { st t; t=stone[a]; stone[a]=stone[b]; stone[b]=t; } void siftdown(int i) { int t,flag=0; while((i<<1)<=n&&flag==0) { if(stone[i].pos>stone[i<<1].pos||(stone[i].pos==stone[i<<1].pos&&stone[i].dis>stone[i<<1].dis)) { t=i<<1; } else t=i; if((i<<1|1)<=n) { if(stone[t].pos>stone[i<<1|1].pos||(stone[t].pos==stone[i<<1|1].pos&&stone[t].dis>stone[i<<1|1].dis)) { t=(i<<1|1); } } if(t!=i) { swap(t,i); i=t; } else flag=1; } } int main() { int t,tt; scanf("%d",&t); for(tt=0;tt<t;tt++) { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%d",&stone[i].pos,&stone[i].dis); } for(int i=n/2;i>=1;i--) { siftdown(i); } int step=0; int ans; while(n>0) { step++; if(step&1) { stone[1].pos+=stone[1].dis; ans=stone[1].pos; siftdown(1); } else { stone[1]=stone[n]; n--; siftdown(1); } } printf("%d ",ans); } }
然后屌丝发现c++里边有优先队列的容器:priority_queue
贴容器的使用方法(其实并不怎么懂,只是会用了):
#include<stdio.h> #include<queue> using namespace std; struct st { int pos,dis; }; struct cmp { bool operator()(const st &a,const st &b) { if(a.pos!=b.pos) return a.pos>b.pos; return a.dis>b.dis; } }; st stone[100010]; int main() { int t,tt,n; priority_queue<st,vector<st>,cmp>q; scanf("%d",&t); for(tt=0;tt<t;tt++) { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%d",&stone[i].pos,&stone[i].dis); q.push(stone[i]); } int step=0,ans; st ttt; while(!q.empty()) { step++; ttt=q.top(); q.pop(); if(step&1) { ttt.pos+=ttt.dis; q.push(ttt); } if(q.empty()){printf("%d ",ttt.pos);} } } //printf("%d ",ans); }