POJ 2051 argus(简单题,堆排序or优先队列)

又是一道数据结构题,使用堆来进行权值调整和排序,每次调整都是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;
}

 

posted @ 2018-04-05 19:04  KYSpring  阅读(165)  评论(0编辑  收藏  举报