zoukankan      html  css  js  c++  java
  • 0x05 排序

    说是排序结果就是各种奇技淫巧

    中位数被坑多了久病成医,例题一题搞笑一题糖果传递(昨晚精神那么好效率还那么差)

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    
    int n,m,T;
    LL X[110000],Y[110000],s[110000];
    LL reX()
    {
        LL ave=T/n;
        for(int i=1;i<=n;i++)s[i]=s[i-1]+ave-X[i];
        sort(s+1,s+n+1);
        LL ret=0;
        for(int i=1;i<=n;i++)
            ret+=abs(s[i]-s[(n+1)/2]);
        return ret;
    }
    LL reY()
    {
        LL ave=T/m;
        for(int i=1;i<=m;i++)s[i]=s[i-1]+ave-Y[i];
        sort(s+1,s+m+1);
        LL ret=0;
        for(int i=1;i<=m;i++)
            ret+=abs(s[i]-s[(m+1)/2]);
        return ret;
    }
    
    int main()
    {
        int x,y;
        scanf("%d%d%d",&n,&m,&T);
        for(int i=1;i<=T;i++)
            scanf("%d%d",&x,&y), X[x]++, Y[y]++;
        if(T%n==0&&T%m==0)printf("both %lld
    ",reX()+reY());
        else if(T%n==0)printf("row %lld
    ",reX());
        else if(T%m==0)printf("column %lld
    ",reY());
        else printf("impossible
    ");
        return 0;
    }
    bzoj3032

    有一个叫对顶堆“算法”的东西,超级搞笑,就是在线求中位数,用两个堆一个存一半,应该是因为我见过类似的套路bzoj3192: [JLOI2013]删除物品,就没意思了。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    using namespace std;
    typedef long long LL;
    
    priority_queue<int> h;
    priority_queue< int,vector<int>,greater<int> > t;
    
    int aslen,as[11000];
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            int zz,n;
            scanf("%d%d",&zz,&n);
            while(!h.empty())h.pop();
            while(!t.empty())t.pop();
            
            aslen=0;int x,mid;
            h.push(-2147483647);
            t.push(2147483647);
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&x);
                if(i%2==1)
                {
                         if(x<h.top()) mid=h.top(), h.pop(), h.push(x);
                    else if(t.top()<x) mid=t.top(), t.pop(), t.push(x);
                    else mid=x;
                    as[++aslen]=mid;
                    h.push(mid);
                }
                else
                {
                         if(x<h.top()) t.push(h.top()) ,h.pop() , h.push(x);
                    else                h.push(t.top()) ,t.pop() , t.push(x);
                    
                         if(h.size()>t.size()) t.push(h.top()) ,h.pop();
                    else if(h.size()<t.size()) h.push(t.top()) ,t.pop();
                }
            }
            
            printf("%d %d
    ",zz,aslen);
            for(int i=1;i<=aslen;i++)
            {
                printf("%d ",as[i]);
                if(i%10==0)printf("
    ");
            }
            if(aslen%10!=0)printf("
    ");
        }
        return 0;
    }
    poj3784

    好像有个O(n)求第k大,但是没有例题口胡一下,就相当于splay的做法,分成左右两个区域,然后判断tot和k应该往哪边。

    我觉得这东西应该没什么用,只问第k大的没多少吧,而且假如是在线问题的话肯定问很多次,每次O(n)太慢了2333

    逆序对就没什么东西了(毕竟也是会cdq分治的)

    但是n*m数码问题的有解性判定没见过,虽然简单就不口胡了。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    int n,m;
    int len,ans,a[1100000],tt[1100000];
    void fenzi(int l,int r)
    {
        if(l==r)return ;
        int mid=(l+r)/2;
        fenzi(l,mid);fenzi(mid+1,r);
        
        int i=l,j=mid+1,p=l;
        while(i<=mid&&j<=r)
        {
            if(a[i]<=a[j])
            {
                ans+=j-(mid+1);
                tt[p++]=a[i++];
            }
            else
            {
                tt[p++]=a[j++];
            }
        }
        while(i<=mid)
        {
            ans+=j-(mid+1);
            tt[p++]=a[i++];
        }
        while(j<=r)
        {
            tt[p++]=a[j++];
        }
        
        for(int i=l;i<=r;i++)a[i]=tt[i];
    }
    int main()
    {
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            if(n==0&&m==0)break;
            int dis;len=0;
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                {
                    len++;
                    scanf("%d",&a[len]);
                    if(a[len]==0)dis=n-i,len--;
                }
            ans=0;fenzi(1,len);
                 if(m%2==1&&ans%2==0)printf("YES
    ");
            else if(m%2==0&&(ans+dis)%2==0)printf("YES
    ");
            else printf("NO
    ");
        }
        return 0;
    }
    poj2893
  • 相关阅读:
    js的浅拷贝与深拷贝
    用Nodejs连接MySQL(原文链接)
    HTML5交互性图表库
    GitHub Desktop离线安装包
    docker--Dockerfile--sonarqube
    docker --Nexus仓库
    docker --Dockerfile--一些语法
    zookeeper 四字命令
    docker --swarm创建一个集群
    docker --swarm启动2375端口监听
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/9237125.html
Copyright © 2011-2022 走看看