zoukankan      html  css  js  c++  java
  • 中南大学oj:1352: New Sorting Algorithm

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1352

    题意:就是要将7 1 5 2这样的序列变成1  2  5  7最少需要多少步?给出变的规律,每次把最前面的那个数移动到比它次小的数的后面,要是它后面没有比它次小的数,就移动到最后,问最少需要多少步?

    For example, we will use 7 steps to sort the sequence 7 1 5 2:
        7 1 5 2 --> 1 5 7 2 --> 5 7 2 1 --> 7 2 5 1 --> 2 5 7 1 --> 5 7 1 2 --> 7 1 2 5 --> 1 2 5 7

    思路:这个题目给出的数据量很大,所以一步步模拟肯定超时。那么就只能是看各种数字移动到它最终位置是否存在一定规律......经过思考,发现好像没有什么规律....于是这道题目我就放弃了.....然后我的一个队友说,一个数移动到它次小的数后面,那么就可以把这两个数合并成一个数,然后再找再合并.....这样时间复杂度会减少很多。的确是这样的,合并完之后,我们只需要用个并查集来统计有多少个数合并在一起了,然后每次移动的时候,把这些数加上即可.......只是,这样还有一个问题,如何找到比它次小的数?如果次小的数已经被合并了呢?......暴力去查找,明显耗时会很大,可能会超时,那么可以把数据进行离散化,由于所以数字都是独一无二的,那么在找次小的数的时候,我们只需要find(x-1)即可........

    #include<iostream> 
    #include<cstdio> 
    #include<queue> 
    #include<cstring> 
    #include<algorithm> 
    using namespace std; 
    #define inf 100005 
    typedef long long ss; 
    ss father[inf],rank[inf]; 
    ss a[inf],b[inf],n; 
    queue<ss>q; 
    queue<ss>q1; 
    ss erfen(ss sum) 
    { 
        ss ll=0,rr=n-1; 
        while(ll<=rr) 
        { 
            ss mid=(ll+rr)/2; 
            if(b[mid]>sum) 
            rr=mid-1; 
            else    ll=mid+1; 
        } 
        return rr; 
    } 
    ss find(ss x) 
    { 
        ss i=x,root; 
        while(x!=father[x]) 
        x=father[x]; 
        root=x; 
        x=i; 
        while(x!=father[x]) 
        { 
            i=father[x]; 
            father[x]=root; 
            rank[root]+=rank[x]; 
            rank[x]=0; 
            x=i; 
        } 
        return root; 
    } 
      
    void liantong(ss x,ss y) 
    { 
        father[x]=y; 
        rank[y]+=rank[x]; 
        rank[x]=0; 
    } 
    int main() 
    { 
        ss text; 
        scanf("%lld",&text); 
        while(text--) 
        { 
            scanf("%lld",&n); 
            while(!q.empty()) 
            q.pop(); 
      
            while(!q1.empty()) 
            q1.pop(); 
            for(ss i=0;i<n;i++) 
            { 
                scanf("%lld",&a[i]); 
                b[i]=a[i]; 
                father[i]=i; 
                rank[i]=1; 
            } 
            sort(b,b+n); 
            //int ll=1,rr=n-1; 
            for(ss i=0;i<n;i++) 
            { 
                a[i]=erfen(a[i]); 
            } 
      
            for(ss i=0;i<n;i++) 
            { 
                q.push(a[i]); 
            } 
            ss ans=0; 
            while(!q.empty()) 
            { 
                ss x=q.front(); 
                q.pop(); 
                if(!q.empty()) 
                { 
                    if(x==0) 
                    { 
                        ss flg=0; 
                        ss tmp=x; 
                        while(!q.empty()) 
                        { 
                            ss y=q.front(); 
                            if(tmp<y) 
                            tmp=y; 
                            else flg=1; 
                            q.pop(); 
                            q1.push(y); 
                        } 
                        if(flg==1) 
                        { 
                            while(!q1.empty()) 
                            { 
                                ss y=q1.front(); 
                                q1.pop(); 
                                q.push(y); 
                            } 
                            q.push(x); 
                            ans+=rank[x]; 
                        } 
                        else break; 
                    } 
                    else
                    { 
                        ans+=rank[x]; 
                        ss y=find(x-1); 
                        if(x!=y) 
                        { 
                            liantong(x,y); 
                        } 
                    } 
                } 
            } 
            printf("%lld
    ",ans); 
        } 
        return 0; 
    } 
    
  • 相关阅读:
    strstr 的使用
    提取文本中的单词,单词简单排序
    sort 与 qsort
    AC自动机妙用
    字符串中如何提取数值
    字符串提取问题
    字符串搜索
    最短路问题
    树莓派挂载移动硬盘
    Mac 更换桌面背景崩溃(闪退)
  • 原文地址:https://www.cnblogs.com/ziyi--caolu/p/3476572.html
Copyright © 2011-2022 走看看