标签: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; }
代码解释的很全。个人感觉这种题只是考一个模板,我也不知道康托展开式在算法比赛中有啥用。。希望高手可以告诉我康托展开式可以做啥~
标签:style blog http color os io for 数据 div
原文地址:http://www.cnblogs.com/ltwy/p/3934384.html