Description
The isolated people of MacGuffin Island have a unique culture, and one of the most interesting things about them is their language. Their alphabet consists of the first 9 letters of the Roman alphabet (a, b, c, d, e, f, g, h, i). All of their words are exactly 9 letters long and use each of these 9 letters exactly once. They have a word for every possible permutation of these letters. In the library of their most sacred temple is a dictionary, and each word in their language has its own page. By coincidence they order their words exactly as they would be in ordered in English, so the word ‘abcdefghi’ is on the first page, and the word ‘ihgfedcba’ is on the last. The question is, given a list of random words from the MacGuffin language, can you say on which page of the MacGuffin dictionary each appears?
Input
The first line of the input file is a positive integer. This integer tells you how many words will follow. The upper limit for this number is 6000. Every subsequent line contains a single word from the MacGuffin language, so if the first number is 1000 there will be 1000 lines after it, each containing a single word.
Output
Each line of output will contain an integer. This integer should be the page number for the corresponding word.
Sample Input
4 abcdefgih abcdefghi abcdefgih ihgfedcba
Sample Output
2 1 2 362880
题解:abcdefgh为字典的第一页,后面排列的组合页码一次递增。问给定一个字符串,求出它在字典里的页码数。
分析:将字符串的字母进行全排列,应用康托展开撒原理
此为9个字符,第一字符对应的权值为8!,依次到最后一个字符权值为0!
对应权值的系数为,比当前为字符小的个数,也包括当前位前面的字符也要进行考虑是否排除掉。
举例分析:
例如一个 list[]={1,2,3,4}
求2341 是第几个数。
所以比第一个数2小的数有一个即为1,对应权值为3!,相乘得1*3!#include<map> #include<set> #include<cmath> #include<ctime> #include<stack> #include<queue> #include<cstdio> #include<cctype> #include<bitset> #include<string> #include<vector> #include<cstring> #include<iostream> #include<algorithm> #include<functional> using namespace std; int jc(int n) { if (n==0) return 1; int sum=1; for (int i=1;i<=n;i++) { sum*=i; } return sum; } int del(vector<int> v,int i) { int cou=0; for (vector<int>::iterator it=v.begin();it!=v.end();it++) { if (*it<i) cou++; } return cou; } int main() { char s[9]; int n; int in; cin >> n; int sum=0; for (int i=0;i<n;i++) { sum = 0; cin >>s; int k=8; vector <int> v; for (int h=1;h<=9;h++) v.push_back(h); for (int j=0;j<9;j++) { in=s[j]-'a'+1; //cout <<in; //cout << jc(k)<<endl; sum+=del(v,in)*jc(k); //cout << sum<<endl; //cout << del(v,in)<<endl; v.erase(remove(v.begin(),v.end(),in)); k--; } cout << sum+1<<endl; } }
第二个为3,比3小的数有1,2两个,排除前面出现的2,即只有1个数比它小,对应权值为2!,相乘得1*2!
第三个为4,比4小的数有1,2,3三个,排除前面出现过的1,2,即只有一个数比它小,对应权值为1!,相乘得1*1!
第四个数为1,没有比它小的数,即为0个,对应权值为0!,相乘得0*0!
即位置为 position=1*3!+1*2!+1*1!+0*0!+1
最后加1是加上第一数的位置。
下面见代码