zoukankan      html  css  js  c++  java
  • 【ACM】nyoj_143_第几是谁_201308071558

    第几是谁?
    时间限制:3000 ms  |  内存限制:65535 KB
    难度:3
    描述
    现在有"abcdefghijkl”12个字符,将其按字典序排列,如果给出任意一种排列,我们能说出这个排列在所有的排列中是第几小的。但是现在我们给出它是第几小,需要你求出它所代表的序列.
    输入
    第一行有一个整数n(0<n<=10000);
    随后有n行,每行是一个整数m,它代表着序列的第几小;
    输出
    输出一个序列,占一行,代表着第m小的序列。
    样例输入
    3
    1
    302715242
    260726926

    样例输出
    abcdefghijkl
    hgebkflacdji
    gfkedhjblcia

    #include <stdio.h>
    #define LEN 12
    int JC(int n)
    {
        int i,sum=1;
        for(i=1;i<=n;i++)
        sum*=i;
        return sum;
    }
    int main()
    {
        int N;
        scanf("%d",&N);
        while(N--)
        {
            int i,j,k,t,m;
            char str[]="abcdefghijkl";
            char a[15];
            scanf("%d",&m);
            m-=1;
            for(i=0;i<LEN;i++)
            {
                t=m/JC(LEN-i-1);
                for(j=0;j<LEN;j++)
                {
                    if(str[j]!='0')//判断str[j]是否用过,与下面 str[j]='0';对应
                    {
                        if(t==0)
                        break;   //如果t=0,结束内循环
                        t--;     //此语句作用很大 如果刚开始 T=6 for循环的作用就是:让a[j]不断的向后移动并跳过已经出现过的字母 很强大。
                    }
                }
                a[i]=str[j];
                str[j]='0';     //标记,表示这个字母已经使用过
                m%=JC(LEN-i-1);
            }
            a[12]='';   
            printf("%s ",a);       
        }
        return 0;
    }

    //参考代码如下:
    /*
    #include"stdio.h"
    #include"stdlib.h"
    int main()
    {
    int fac[]={1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800,479001600};//矩阵表
    int n=12,k,i,j,t,m;
    char s[14];//存放序列
    scanf("%d",&m);

    while(m--)
    {
    char a[13]="abcdefghijkl";//字母列表
    scanf("%d",&k);
    k=k-1;
    for(i=0;i<n;i++)//进行12次循环
    {
    t=k/fac[n-i-1];//求出T是一个数

    for(j=0;j<n;j++)
    if(a[j]!='0')//与下句的a[j]='0',相呼应,检验是否该字母已经被用过。
    {
    if(t==0) break;//t为0 就直接跳出最内层的循环
    t--; //此语句作用很大 如果刚开始T=6 for循环的作用就是:让a[j]不断的向后移动并跳过已经出现过的字母 很强大。
    }
    s[i]=a[j];
    a[j]='0';//此语句起标记作用,标记字母标中的该字母已经用过。

    k%=fac[n-i-1];
    }
    s[12]='';
    printf("%s ",s);
    }
    system("pause");
    return 0;
    }
    */

    康托展开--逆运算

     {1,2,3,4,5}全排列,并且已经从小到大排序完毕

    (1)找出第96个数

    首先用96-1得到95

    95去除4! 得到323

    3个数比它小的数是4

    所以第一位是4

    23去除3! 得到35

    3个数比它小的数是44已经在之前出现过了所以第二位是54在之前出现过,所以实际比5小的数是3个)

    5去除2!得到21

    2个数比它小的数是3,第三位是3

    1去除1!得到10

    1个数比它小的数是2,第二位是2

    最后一个数只能是1

    所以这个数是45321

    (2)找出第16个数

    首先用16-1得到15

    15去除4!得到015

    15去除3!得到23

    3去除2!得到11

    1去除1!得到10

    0个数比它小的数是1

    2个数比它小的数是但由于1已经在之前出现过了所以是4(因为1在之前出现过了所以实际比4小的数是2

    1个数比它小的数是但由于1已经在之前出现过了所以是3(因为1在之前出现过了所以实际比3小的数是1

    1个数比它小得数是但由于134已经在之前出现过了所以是5(因为134在之前出现过了所以实际比5小的数是1

    最后一个数只能是2

    所以这个数是1435

  • 相关阅读:
    软件的概念
    打开别人Android项目的方法
    软件工程
    数据预处理技术
    机器学习之监督学习
    C语言指针与二维数组
    徐涛政治押题
    求二叉树的宽度
    解决在某些IE浏览器下字符乱码的问题
    mac系统不能使用127.0.0.2的解决方案
  • 原文地址:https://www.cnblogs.com/xl1027515989/p/3243364.html
Copyright © 2011-2022 走看看