zoukankan      html  css  js  c++  java
  • 算法笔记--康托展开

    X表示一个排列在所有的全排列中排第几个(从0开始)。

    X=a[0]*(n-1)!+a[1]*(n-2)!+...+a[i]*(i-1)!+...+a[n-1]*0! ,其中a[i]为在当前未出现的元素中是排在第几个(从0开始)(或者说下标i后面值比i这位置值小的个数),这就是康托展开。

    逆康托展开就是把X除以(n-1)!得到a[0],然后再对(n-1)!取模,以此类推,分别求出a[0]a[n-1]

    例题:https://projecteuler.net/problem=24

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    
    int fac[11]={1,1,2,6,24,120,720,5040,40320,362880,3628800};
    bool vis[11];
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int t=1000000-1;
        int cnt=9;
        while(true)
        {
            int tt=t/fac[cnt];
            int tot=0;
            for(int i=0;i<=9;i++)
            {
                if(!vis[i])
                {
                    if(tot==tt)cout<<i,vis[i]=true;
                    tot++;
                }
            }
            t=t%fac[cnt];
            cnt--;
            if(cnt==-1)break;
        }
        return 0;
    }
  • 相关阅读:
    java中级或者高级面试题分享
    java常使用的框架
    spring的定时器
    ArrayList源码理解
    缓存 Memached
    ORM框架
    Web处理方式
    git使用
    Entity Framework
    .net 学习笔记2
  • 原文地址:https://www.cnblogs.com/widsom/p/8110764.html
Copyright © 2011-2022 走看看