cus1828:dictionary

探讨一种独特文化中的语言——MacGuffin岛民的语言。这种语言由9个罗马字母组成,每个单词长度固定为9个字母,并且每个字母只使用一次。通过解析这种语言的字典排序原理,介绍如何计算给定单词在字典中的位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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是加上第一数的位置。
下面见代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值