zoukankan      html  css  js  c++  java
  • 杭电1027

    题意:有整数元素1到n,最小的序列定义为1,2,3……,n-1,n,倒数第二小的是1,2,3,……,n,n-1,倒数第三小的是1,2,3,……,n-1,n-2,n。求倒数第m小的序列。

    Analyse:

    拿第一个实例开始分析:原本的数列是1,2,3,4,5,6,若要第1个最小的数列,则需要改变最后1个数字的顺序,若要第2个最小的数列,则需要改变最后2个数字的顺序,若要第3个最小的数列,则需要改变最后3个数字的顺序,若要第4个最小的数列,则需要改变最后3个数字的顺序。要第m个最小的数列,我们需要改变最后k((k-1)!<m<=k!)个数字的顺序。

    因为要的数列是第四个最小的数列,因此要改变4,5,6的顺序,4,5,6的全排列为3!=6,4??,5??,6??分别有两种排列,进而知道后面的内容是5??,5的第2个排列;剩下4,6全排列为2!=2,用同样的方法确定为6?,然后确定4。

    View Code
     1 #include<stdio.h>
    2 main()
    3 {
    4 int ele[1010],fact[10]={1,1,2,6,24,120,720,5040,40320};
    5 int i,n,m,start,leftN,unit,mth;
    6 while(scanf("%d%d",&n,&m)!=EOF)
    7 {
    8 for(i=1;i<=8 && m>fact[i];i++);
    9 start=n-i+1;//start为开始改变顺序的数字
    10 for(i=1;i<start;i++)
    11 printf(i==1?"%d":" %d",i);//先输出不需改变顺序的数字
    12 for(i=start;i<=n;i++)
    13 ele[i]=1;//要改变顺序的数字都先标记为1(可用)
    14 leftN=n-start+1;//leftN为要改变顺序的数字的数目
    15 while(leftN>0)
    16 {
    17 unit=fact[leftN-1];//fact[leftN]/leftN==fact[leftN]
    18 mth=m%unit==0?m/unit:m/unit+1;
    19 m=m%unit==0?unit:m%unit;
    20 for(i=start;i<=n && mth>0;i++)
    21 {
    22 if(ele[i]==1)
    23 mth--;
    24 }
    25 ele[i-1]=0;
    26 printf(" %d",i-1);
    27 leftN--;
    28 }
    29 putchar('\n');
    30 }
    31 }



  • 相关阅读:
    Leetcode 538. Convert BST to Greater Tree
    Leetcode 530. Minimum Absolute Difference in BST
    Leetcode 501. Find Mode in Binary Search Tree
    Leetcode 437. Path Sum III
    Leetcode 404. Sum of Left Leaves
    Leetcode 257. Binary Tree Paths
    Leetcode 235. Lowest Common Ancestor of a Binary Search Tree
    Leetcode 226. Invert Binary Tree
    Leetcode 112. Path Sum
    Leetcode 111. Minimum Depth of Binary Tree
  • 原文地址:https://www.cnblogs.com/ZShogg/p/2428844.html
Copyright © 2011-2022 走看看