美文网首页
求第一百万个字典序排列数

求第一百万个字典序排列数

作者: 默写年华Antifragile | 来源:发表于2019-08-12 22:34 被阅读0次

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

A permutation is an ordered arrangement of objects. For example, 3124 is one possible permutation of the digits 1, 2, 3 and 4. If all of the permutations are listed numerically or alphabetically, we call it lexicographic order. The lexicographic permutations of 0, 1 and 2 are:

012 021 102 120 201 210

What is the millionth lexicographic permutation of the digits 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9?

题目大意:

求 (0,1,2,3,4,5,6,7,8,9) 的第一百万个字典序排列

解题思路:

  • 直接一个一个进行DFS会比较耗时
  • 可以通过数学方法来进行判断,从左往右,最高位上有10种数字选择,最高位上选定后,对应后面共有9!种排列,因此对于最高位上,从0,1,2,3...开始,每个数字共有9!种排列,比如,最高位初始从0开始,共有9!种排列;接下来,最高位为1,又有9!种排列;然后最高位为2,又有9!种排列;此时一共有 3*9!种排列,此时已经超过一百万,因此,最高位为2时,并没有排完每一个排列;因此把最高位定为2,根据一百万减去前面的排列数目,即接下来要求的排列数目,确定次高位,依次确定每一位;
    • 这里要注意如果刚好排完,即比如最开始要求的就是求第10!个排列,就是求当前剩余数字的最后一个排列,即把剩下的数字按照从大到小的顺序排列即可

代码如下:

#include<iostream>
#include<cstring>
using namespace std;

int main()
{
    int i = 0;
    int j = 0;
    int left[10] = {0};
    int used[10]={0};
    long temp = 1;
    long temp_10 = 1;
    long num = 1000000; // 注意整除时的情况

    for(i = 0; i < 10; ++ i)
    {
        if(num==0) // 特殊情况,如果能够整除,那么说明是当前剩下数字的最后一个排列,即这个排列就是从大到小进行排列
        {
            for(j = 9; j >=0; --j)
                if(used[j]==0)
            {
                left[i] = j;
                ++i;
            }
        }
        else // 一般情况,计算每一位上的每个数字有多少种组合,然后确定当前的数字
            {
                temp = 1;
                for(j = 10-i; j > 0; --j)
                {
                    temp *= j;
                }
                temp_10 *= 10;
                temp /= (10-i);
                left[i] = num / temp;
                num = num - left[i]*temp;

                int count = 0;
                for(j = 0; j < 10; ++j)
                {
                    if(num !=0 && count == (left[i]+1))// 如果能整除,那么应该是第 left[i] + 1 个数字
                        break;
                    else if(num==0 && count==left[i]) // 如果不能整除,那么应该是第 left[i] 个数字
                        break;
                    if(used[j] == 0)
                       ++count;
                }
                left[i] = j-1;
                used[left[i]]=1;
            }
    }
    for(i = 0; i < 10; ++i)
    {
        printf("%d",left[i]);
    }
}

相关文章

  • 求第一百万个字典序排列数

    原题:https://projecteuler.net/problem=24 A permutation is a...

  • JavaScript#31:数组--(字典排序)Next Per

    求一个序列的下一个全排列...........按照字典序。 所谓字典序,比如说 123三个数字组成的全排列就有: ...

  • Permutations

    求一个数组的全排列。 遇到的问题: 1.忘记了字典序排列的定义;2.思考时间过长;3.没有及时找到全排列和字典序之...

  • 全排列

    问题描述 求1-n的所有按字典序的全排列 C++实现

  • 字典序排列

    字符串的全排列,普通递归如下: 详细的解析:http://blog.csdn.net/randyjiawenjie...

  • 下一个排列

    下一个排列 n个元素有n!种排列方式,你不会想都罗列出来再去找下一个排列吧 这种排序方式为字典序,字典序就是将元素...

  • leetcode力扣 46 全排列

    借着这个题,复习一下全排列:以下介绍全排列算法四种: (A)字典序法 (B)递增进位制数法 (C)递减进位制数法 ...

  • 排列组合的实现

    C语言中的排列和组合在实际的应用中使用广泛。排列算法*字典序法*递增进位制数法*递减进位制数法*邻位对换法*递归法...

  • 字典序生成排列

  • JZ-027-字符串的排列

    字符串的排列 题目描述 输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则按字典序打...

网友评论

      本文标题:求第一百万个字典序排列数

      本文链接:https://www.haomeiwen.com/subject/lgbpjctx.html