csuoj1828Dictionary (康托展开)
2017-08-25 14:11
232 查看
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
这个就是裸的求康托展开
九位数先把阶乘打表(这么小的数打不打其实无所谓)
康托展开的大意就是一个排列在它的全排列中按字典序排序时所处位置
比如213,它的全排列有123、132、213、231、312、321(已按字典序排好),所以它的康托展开为2,没错是2,因为康托展开是从0开始计数
的,所以学长教我们一个新的记法——康托展开的大小即为在此排列前存在的排列的个数。
求法自然有公式的呀——
表示第i个元素在未出现的元素中排列第几,n的大小为字符串的长度
比如213这个例子,n=3,然后2排第1,所以a3=1,1排第0,所以a2=0,3排第2,所以a3=2,所以
ans=1*2+0*1+2*0=2
代码
#include<iostream>
#include<cstdio>
using namespace std;
#define ll long long
int f[10];
void init()
{
f[1]=1;
for(int i=2;i<10;i++)
f[i]=f[i-1]*i;
}
int main()
{
int N,M;
char s[10];
init();
scanf("%d",&N);
while(N--)
{
int ans=0;
scanf("%s",s);
for(int i=0;i<9;i++)
{
int temp=0;
for(int j=i+1;j<9;j++)
if(s[j]<s[i])temp++;
ans+=temp*f[9-i-1];
}
printf("%d\n",ans+1);
}
return 0;
}
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
这个就是裸的求康托展开
九位数先把阶乘打表(这么小的数打不打其实无所谓)
康托展开的大意就是一个排列在它的全排列中按字典序排序时所处位置
比如213,它的全排列有123、132、213、231、312、321(已按字典序排好),所以它的康托展开为2,没错是2,因为康托展开是从0开始计数
的,所以学长教我们一个新的记法——康托展开的大小即为在此排列前存在的排列的个数。
求法自然有公式的呀——
表示第i个元素在未出现的元素中排列第几,n的大小为字符串的长度
比如213这个例子,n=3,然后2排第1,所以a3=1,1排第0,所以a2=0,3排第2,所以a3=2,所以
ans=1*2+0*1+2*0=2
代码
#include<iostream>
#include<cstdio>
using namespace std;
#define ll long long
int f[10];
void init()
{
f[1]=1;
for(int i=2;i<10;i++)
f[i]=f[i-1]*i;
}
int main()
{
int N,M;
char s[10];
init();
scanf("%d",&N);
while(N--)
{
int ans=0;
scanf("%s",s);
for(int i=0;i<9;i++)
{
int temp=0;
for(int j=i+1;j<9;j++)
if(s[j]<s[i])temp++;
ans+=temp*f[9-i-1];
}
printf("%d\n",ans+1);
}
return 0;
}
相关文章推荐
- USACO / Stringsobits (DP构造/康托展开)
- 康托展开和逆康托展开
- nyoj__139__143__康托展开和康托逆展开
- POJ 1077 搜索利用康托展开。。。
- 【数学】康托和逆康托展开(全排列顺序问题)
- HDU 3567 Eight II 打表,康托展开,bfs,g++提交可过c++不可过 难度:3
- vijos - P1092全排列 (康托展开 + 康托展开的逆运算)
- LightOJ1060 nth Permutation(不重复全排列+逆康托展开)
- 我排第几个——康托展开
- poj 1077(BFS预处理+康托展开)
- 康托展开
- 全排列方法二(康托展开)
- nyoj 139 我排第几个(康托展开)
- 康托展开:对全排列的HASH和还原,判断搜索中的某个排列是否出现过
- HDU 1043 全排列 康托展开
- HDU 1430 DFS + 康托展开 + 映射处理 +预处理!
- 康托展开
- 浅谈康托展开与其逆.
- 康托展开
- HDU_1430——魔板,预处理,康托展开,置换,string类的+操作