zoukankan      html  css  js  c++  java
  • 1098 Insertion or Heap Sort (25 分)

    题意

    给出一个初始序列,可以对它使用插入排序或堆排序法进行排序。现在给出一个序列,试判断它是由插入排序还是堆排序产生的,并输出下一步将会产生的序列。

    思路

    本题与A1089非常类似,需要直接模拟插入排序和堆排序的每一步过程。

    具体做法为:先进行插入排序,如果执行过程中发现与给定序列吻合,那么说明是插入排序,计算出下一步将会产生的序列后结束算法;如果不是插入排序,那么一定是堆排序,模拟堆排序的过程,如果执行过程中发现与给定序列吻合,那么计算出下一步将会产生的序列后结束算法。

    注意点

    1. 本题参考代码中插入部分直接用sort实现,可以节省编码时间。
    2. 和A1089一样的陷阱:初始序列不参与比较是否与目标序列相同(也就是说,题目中说的中间序列是不包括初始序列的)。
    3. 要求从小到大排序,因此用大根堆,每次把最大值放到序列结尾。
    const int N=1010;
    int a[N],b[N];
    int heap[N];
    int n;
    
    bool isSame(int a[])
    {
        for(int i=1;i<=n;i++)
            if(a[i] != b[i])
                return false;
        return true;
    }
    
    //bool InsertSort()
    //{
    //    bool ok=false;
    //    for(int i=2;i<=n;i++)
    //    {
    //        if(isSame(a) && i != 2) ok=true;
    //        int t=a[i];
    //        int j=i;
    //        while(j && a[j-1] > t)
    //        {
    //            a[j]=a[j-1];
    //            j--;
    //        }
    //        a[j]=t;
    //
    //        if(ok) return true;
    //    }
    //    return false;
    //}
    
    bool InsertSort()
    {
        bool ok=false;
        for(int i=2;i<=n;i++)
        {
            if(isSame(a) && i != 2) ok=true;
    
            //插入部分直接用sort代替
            sort(a+1,a+i+1);
            if(ok) return true;
        }
        return false;
    }
    
    void down(int u,int n)
    {
        int j=u*2;
        while(j <= n)
        {
            if(j<n && heap[j] < heap[j+1])
                j++;
            if(heap[u] < heap[j])
            {
                swap(heap[u],heap[j]);
                u=j;
                j=u*2;
            }
            else
                break;
        }
    }
    
    void CreateHeap()
    {
        for(int i=n/2;i>=1;i--)
            down(i,n);
    }
    
    void HeapSort()
    {
        CreateHeap();
    
        bool ok=false;
        for(int i=n;i>=1;i--)
        {
            if(isSame(heap) && i != n) ok=true;
    
            swap(heap[1],heap[i]);
            down(1,i-1);
    
            if(ok) break;
        }
    }
    
    void print(int a[])
    {
        for(int i=1;i<=n;i++)
            if(i>1) cout<<' '<<a[i];
            else cout<<a[i];
        cout<<endl;
    }
    
    int main()
    {
        cin>>n;
    
        for(int i=1;i<=n;i++) cin>>a[i],heap[i]=a[i];
        for(int i=1;i<=n;i++) cin>>b[i];
    
        if(InsertSort())
        {
            puts("Insertion Sort");
            print(a);
        }
        else
        {
            puts("Heap Sort");
            HeapSort();
            print(heap);
        }
    
        //system("pause");
        return 0;
    }
    
  • 相关阅读:
    【Foreign】数数 [打表][DP]
    【Foreign】猜测 [费用流]
    【Foreign】最大割 [线性基]
    【Foreign】开锁 [概率DP]
    【Foreign】染色 [LCT][线段树]
    【Foreign】阅读 [线段树][DP]
    【Foreign】字符串匹配 [KMP]
    【Foreign】冒泡排序 [暴力]
    【BZOJ1976】能量魔方 [最小割]
    【Foreign】树 [prufer编码][DP]
  • 原文地址:https://www.cnblogs.com/fxh0707/p/14520732.html
Copyright © 2011-2022 走看看