码迷,mamicode.com
首页 > 其他好文 > 详细

NYOJ 139 我排第几个 康托展开式

时间:2014-08-25 11:24:14      阅读:237      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   io   for   数据   div   

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=139

 

思路:康托展开式的典型应用,康托展开式是什么呢,举个例子。1,2,3这三个数的全排列共有六种,那么按照字典的顺序,『3,2,1』 这个序列是在第几个呢。康托是这样想的:

    首先从第一位3开始看,比3小的有2,1,那么也就是说如果第一位是1或者2都在这个序列的前面,那么以1或者2开头的序列有多少呢,答案为2*2!。为什么是这个答案呢?因为符合 要求的第一位共有1和2两个数,然后第二位和第三位组成的排列总数为2!,所以,学过排列组合的都知道,乘起来就可以了(康托展开式本来就是组合数学里面的...)。

 

好了,既然我们明白了康托展开式是什么,下面就可以写代码了。

 

代码如下:

  

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

int jc[]={1,2,6,24,120,720,5040,40320,362880,3628800,39916800};//阶乘数组,记录我们要用到的阶乘 

int book[12]={0};//标记数组,标记有没有用过 

int main()
{
    string temp;//测试数据 
    int num;
    int now;//仅仅作为一个中间变量用 
    int res;//结果 
    int x;//比当前元素小且没有被用过的数量 
    cin>>num;
    while(num--)
    {
        memset(book,0,sizeof(book));
        //初始化结果最小为1 
        res = 1;
        cin>>temp;
        
        for(int i=0;i<12;i++)
        {
            x = 0;
            now = temp[i]-97;
            //标记当前的temp[i]已经用过 
            book[now] = 1;
            //开始找比当前的temp[i]小的元素且没有用过的元素有几个 
            for(int j=0;j<11;j++)
            {
                if(book[j]==0&&now>j)
                    x++;
            }
            
            //找出来的结果 进行相加 
            res += jc[10-i]*x;
        }
        
        cout<<res<<endl;
    }
    return 0;
}

代码解释的很全。个人感觉这种题只是考一个模板,我也不知道康托展开式在算法比赛中有啥用。。希望高手可以告诉我康托展开式可以做啥~

NYOJ 139 我排第几个 康托展开式

标签:style   blog   http   color   os   io   for   数据   div   

原文地址:http://www.cnblogs.com/ltwy/p/3934384.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!