ACM題目之排列序數

問題 F: S:排列序數

時間限制: 1 Sec  內存限制: 256 MB

題目描述

如果用a b c d這4個字母組成一個串,有4!=24種,如果把它們排個序,每個串都對應一個序號:

  abcd  0

  abdc  1

  acbd  2

  acdb  3

  adbc  4

  adcb  5

  bacd  6

  badc  7

  bcad  8

  bcda  9

  bdac  10

  bdca  11

  cabd  12

  cadb  13

  cbad  14

  cbda  15

  cdab  16

  cdba  17

  ...

現在有不多於10個兩兩不同的小寫字母,給出它們組成的串,你能求出該串在所有排列中的序號嗎?

輸入

包含多組測試數據,每組測試數組佔一行。

輸出

對每組測試數據輸出一行,一個整數,表示該串在其字母所有排列生成的串中的序號。注意:最小的序號是0

樣例輸入

abc
dba

樣例輸出

0
5

第一次寫博客,寫的不好,請大家包容。這是我在ACM最近做的一道題目。當時沒想出來怎麼做,只看出題目的一點點規律,以爲就是把abcd這些替換成1234,然後放到數組裏面進行排序,但是沒弄出來。現在想想弄出來也會超時。(時間限制: 1 Sec)

經過同學的一番指點,知道了規律(規律就是康託展開式!)。比如求adbc的序號就是從a依次到c看其後面有幾個比其小的字母,比方說d,d後面有b和c兩個字母比它小,所以次序就加上(d後面還有幾個字母的階乘)*2=2!*2=4;次序就是4.同理可得dba就是2 ! *2+1!*1=5;

1.康託展開的解釋


康託展開就是一種特殊的哈希函數

  把一個整數X展開成如下形式:

  X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[2]*1!+a[1]*0!

  其中,a爲整數,並且0<=a<i,i=1,2,..,n

  {1,2,3,4,...,n}表示1,2,3,...,n的排列如 {1,2,3} 按從小到大排列一共6個。123 132 213 231 312 321 。

  代表的數字 1 2 3 4 5 6 也就是把10進制數與一個排列對應起來。

  他們間的對應關係可由康託展開來找到。

  如我想知道321是{1,2,3}中第幾個大的數可以這樣考慮 :

  第一位是3,當第一位的數小於3時,那排列數小於321 如 123、 213 ,小於3的數有1、2 。所以有2*2!個。再看小於第二位2的:小於2的數只有一個就是1 ,所以有1*1!=1 所以小於321的{1,2,3}排列數有2*2!+1*1!=5個 
。所以321是第6個大的數。 2*2!+1*1!是康託展開。

  再舉個例子:1324是{1,2,3,4}排列數中第幾個大的數:第一位是1小於1的數沒有,是0個 0*3! 第二位是3小於3的數有1和2,但1已經在第一位了,所以只有一個數2 1*2! 。第三位是2小於2的數是1,但1在第一位,所以 
有0個數 0*1! ,所以比1324小的排列有0*3!+1*2!+0*1!=2個,1324是第三個大數。


代碼如下:

#include<iostream>
#include<cstring>
using namespace std;
int main()
{
    char str[15];
    int q[10]={1},i,j;
    for(i=1;i<10;++i)
        q[i]=i*q[i-1];
   while(cin.getline(str,15))
    {
        int sum=0,k;               //k代表後面比這個字母小的數,sum代表位置
        int l=strlen(str);
        for(i=0;i<l;++i)
        {
            k=0;
            for(j=i+1;j<l;++j)
                if(str[j]<str[i])
            {
                k++;
            }
            sum+=q[l-i-1]*k;
        }
        cout<<sum<<endl;
        memset(str,0,sizeof(str));
   }
  return 0;





}






















發佈了27 篇原創文章 · 獲贊 10 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章