zoukankan      html  css  js  c++  java
  • POJ置换群入门[3/3]

    POJ 3270 Cow Sorting

    题意:

    一个序列变为升序,操作为交换两个元素,代价为两元素之和,求最小代价

    题解:

    看了黑书...

    首先循环因子分解

    一个循环完成的最小代价要么是循环中最小元素依次与其他交换,要么引入全局最小值来交换

    $sum+min(mn*(len-2),mn+Min*(len+1))$

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int N=1e4+5,M=1e5+5;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
        return x*f;
    }
    int n,a[N],c[M],Min=M,m;
    int f[N],ans;
    bool vis[N];
    int main(){
        //freopen("in","r",stdin);
        n=read();
        for(int i=1;i<=n;i++)
            a[i]=read(),c[a[i]]++,Min=min(Min,a[i]),m=max(m,a[i]);
        for(int i=1;i<=m;i++) c[i]+=c[i-1];
        for(int i=1;i<=n;i++) f[i]=c[a[i]];
        for(int i=1;i<=n;i++) if(!vis[i]){
            vis[i]=1;
            int u=f[i],sum=a[i],mn=a[i],len=1;
            while(u!=i) vis[u]=1,sum+=a[u],mn=min(mn,a[u]),len++,u=f[u];
            ans+=sum+min(mn*(len-2),mn+Min*(len+1));
        }
        printf("%d",ans);
    }
    View Code

     

    POJ2369 Permutations

    题意:

    求一个置换的几次幂得到自身

    题解:

    每个循环长度的最小公倍数

    注意是几次幂不是转换了几次!!!

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int N=1e3+5;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
        return x*f;
    }
    int n,a[N],ans=1;
    inline int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
    inline int lcm(int a,int b){return a/gcd(a,b)*b;}
    bool vis[N];
    int main(){
        //freopen("in","r",stdin);
        n=read();
        for(int i=1;i<=n;i++) a[i]=read();
        for(int i=1;i<=n;i++) if(!vis[i]){
            vis[i]=1;
            int u=a[i],len=1;
            while(u!=i) vis[i]=1,len++,u=a[u];
            ans=lcm(ans,len);
        }
        printf("%d",ans);
    }
    View Code

    POJ1721CARDS

    题意:

    交换规则为$i ightarrow a[a[i]]$,进行了$s$次,给出最后的排列求一开始

    题解:

    一直尝试构造置换的逆一直失败,也许是因为每次合成的置换都不同吧

    网上的做法是暴力找整个置换的循环然后把剩下的操作补出来...感觉会被卡...

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int N=1005;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
        return x*f;
    }
    int n,s,a[N],t[N],b[N];
    int main(){
        freopen("in","r",stdin);
        n=read();s=read();
        for(int i=1;i<=n;i++) b[i]=a[i]=read();
        int cnt=0;
        while(true){
            int flag=1;
            cnt++;
            for(int i=1;i<=n;i++) t[i]=a[a[i]];
            for(int i=1;i<=n;i++){
                a[i]=t[i];
                if(a[i]!=b[i]) flag=0;
            }
            if(flag) break;
        }
        cnt=cnt-s%cnt;
        while(cnt--){
            for(int i=1;i<=n;i++) t[i]=a[a[i]];
            for(int i=1;i<=n;i++) a[i]=t[i];
        }
        for(int i=1;i<=n;i++) printf("%d
    ",a[i]);
    }
    View Code
  • 相关阅读:
    LeetCode
    算法
    GitHub
    GitHub
    git
    将博客搬家至CSDN
    base64与图片互转
    windows下mongodb数据库搭建过程遇到问题
    mongodb数据插入语句与navicat导入mongodb的json结构
    Visual C++安装失败解决:Error 0x80240017: Failed to execute MSU package.
  • 原文地址:https://www.cnblogs.com/candy99/p/6477599.html
Copyright © 2011-2022 走看看