又是一道数据结构题,使用堆来进行权值调整和排序,每次调整都是o(n)的复杂度,非常高效。
第一眼看题觉得可以用优先队列来做,应该也很简单。
事实上多数优先队列都是通过堆来实现的。
写的时候还是出了一些问题:
1、二叉树根节点下标显然不能为0;
2、限界之后若出现扩界要小心;
3、在迭代循环比较的时候,尤其注意到底比较的是谁,别把自己绕晕了。
ac代码:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> using namespace std; //纠错方法:带简单样例进去跑,打印错误位置 //二叉树注意编号从1开始 //限界之后扩界敏感 struct node{ int now,no,period; }; const int maxn=3005; node n[maxn]; void down(int p,int len){ int q=p*2; node a=n[p]; while(q<len){ //这里出现死循环,因为我的二叉树是从0开始编号的,而很明显 0*2^n=0; 有点智障的bug if(q+1<len){//这句不能少(限界之后扩界需要再判定越界) if(n[q].now>n[q+1].now){ q++; } else if(n[q].now==n[q+1].now&&n[q].no>n[q+1].no){ q++; } } //if(n[q].now>n[p].now){//比较对象到底是谁 ! if(n[q].now>a.now){ break; } else if(n[q].now==a.now&&a.no<n[q].no){//是a在比较 break; } n[p]=n[q]; p=q,q=2*p; } n[p]=a; } void makeMinheap(int len){ for(int j=(len-1)/2;j>=1;j--){ //cout<<j<<endl; down(j,len); } } int main(void){ string s; cin>>s; int i=1; while(s[0]!=‘#‘){ cin>>n[i].no>>n[i].period; n[i].now=n[i].period; i++; cin>>s; } int len=i; int l; cin>>l; makeMinheap(len); while(l--){ cout<<n[1].no<<endl; n[1].now+=n[1].period; down(1,len); } return 0; }