zoukankan      html  css  js  c++  java
  • Luogu [P1334] 瑞瑞的木板(手写堆)

    其实这个题完全不需要用手写堆,只需要一遍遍sort就行了……

    但是!

    为了练习手写堆,还是用手写堆做了。

    在做本题之前,如果你没有什么思路的话,建议先做Luogu的合并果子

    好,假设你已经做过了合并果子了。那么正式开始本题:

    相信许多人都已经知道了这道题就是合并果子,但是还不知道它是怎样转化成合并果子的,其实很简单:比如说9 7 6 5 3,有些同学可能会想:每次我砍最大的,然后剩下的不就少了。其实不然,因为不一定一次只能砍一个,可以砍两个或两个以上。不多说,我把上面例子的最优策略讲出来大概就知道了。step1:把9+7+6+5+3切成7+6和5+3+9两部分;step2:把7+6切成7和6;step3:把5+3+9切成5+3和9两部分:step4:把5+3切成5和3。这时我们再回过头来看,是不是就是合并果子的步骤?

    AC代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    long long x,n,tot,dl[100001],sum;//小根堆 
    char c;
    void delete_2(long long num)
    {
        if(((num<<1)+1)<=tot)
        {
            if(dl[num<<1]<dl[(num<<1)+1])
            {
                if(dl[num]<dl[num<<1])
                    return ;
                else
                {
                    swap(dl[num],dl[num<<1]);
                    delete_2(num<<1);
                }
            }
            else
            {
                if(dl[num]<dl[(num<<1)+1])
                    return ;
                else
                {
                    swap(dl[num],dl[(num<<1)+1]);
                    delete_2((num<<1)+1);
                }
            }
        }
        else
        {
            if((num<<1)<=tot)
            {
                if(dl[num]<dl[num<<1])
                    return ;
                else
                {
                    swap(dl[num],dl[num<<1]);
                    delete_2(num<<1);
                }
            }
            else
                return ;
        }
        return ;
    }
    
    void delete_1()//删除操作
    {
        dl[1]=dl[tot--];
        delete_2(1);
    }
    
    void qcr(long long num)  //名字随便取的
    {
        if(num==1)
            return ;
        if(dl[num]<dl[num>>1])
        {
            swap(dl[num],dl[num>>1]);
            num>>=1;    
            qcr(num);
        }
        return ;
    }
    
    void putin(long long x)  //添加操作
    {
        dl[++tot]=x;
        qcr(tot);
    }
    
    void putout()     //读取操作
    {
        printf("%d",dl[1]);
        return ;
    } 
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>x;
            putin(x);
        }
        for(int i=1;i<n;i++)
        {
            int q,p;
            q=dl[1];
            delete_1();
            p=dl[1];
            delete_1();
            sum+=p+q;
            putin(p+q);
        }
        cout<<sum;
        return 0;
    }

     

  • 相关阅读:
    C# Net 合并int集合为字符串,如:输入1,2,3,4,8 输出1~4,8
    sql server 安装出现需要sqlncli.msi文件,错误为 microsoft sql server 2012 native client
    C# Form 实现桌面弹幕
    C# Net 去除图片白边
    SQL common keywords examples and tricks
    Excel formula and tricks
    HIghcharts cheatsheet
    CSS common keywords examples and tricks
    小白终于弄懂了:c#从async/await到Task再到Thread
    LeetCode 2: single-number II
  • 原文地址:https://www.cnblogs.com/qiuchengrui/p/8995194.html
Copyright © 2011-2022 走看看