24h購物| | PChome| 登入
2012-07-11 13:43:37| 人氣1,177| 回應0 | 上一篇 | 下一篇

[UVA] 153 - Permalex

推薦 0 收藏 0 轉貼0 訂閱站台


 Permalex 

Given a string of characters, we can permute the individual characters to make new strings. If we can impose an ordering on the characters (say alphabetic sequence), then the strings themselves can be ordered and any given permutation can be given a unique number designating its position in that ordering. For example the string `acab' gives rise to the following 12 distinct permutations:

tabular21

Thus the string `acab' can be characterised in this sequence as 5.

Write a program that will read in a string and determine its position in the ordered sequence of permutations of its constituent characters. Note that numbers of permutations can get very large; however we guarantee that no string will be given whose position is more than tex2html_wrap_inline31 .

Input and Output

Input will consist of a series of lines, each line containing one string. Each string will consist of up to 30 lower case letters, not necessarily distinct. The file will be terminated by a line consisting of a single #.

Output will consist of a series of lines, one for each line of the input. Each line will consist of the position of the string in its sequence, right justified in a field of width 10.

Sample input

bacaa
abc
cba
#

Sample output

        15
         1
         6

其實還蠻怕 30! 會出現的, 所以用了點簡單的做法去避免掉, 就是要算 n!/a!/b!/c! ... 時, 模仿平常做的方式,
因此開一個 int[n]去存儲分子, 然後開始約分 !
bacaa 當要計算這個的時候, 'b' 前面還有幾個字母, 嘗試做為頭
則 可以 'a' 開頭 計算排列 aacb 的個數
'ba' 已經是底線了,
'bac' 可以 'a' 開頭, 計算 aac 的個數 ... 類推

 

#include <stdio.h>
#include <string.h>
int gcd(int x, int y) {
    int t;
    while(x%y) {
        t = x, x = y, y = t%y;
    }
    return y;
}
int main() {
    char s[50];
    while(scanf("%s", s) == 1) {
        if(s[0] == '#')
            break;
        int cnt[26] = {}, len = strlen(s);
        int i, j, k, l, a;
        for(i = 0; s[i]; i++) {
            cnt[s[i]-'a']++;
        }
        long long ans = 0;
        for(i = 0; s[i]; i++) {
            for(j = 0; j < s[i]-'a'; j++) {
                if(cnt[j] == 0) continue;
                cnt[j]--;
                int set[50] = {};
                for(k = 2; k < len-i; k++)
                    set[k] = k;
                for(k = 0; k < 26; k++) {
                    for(l = 2; l <= cnt[k]; l++) {
                        int tmp = l;
                        for(a = 2; a < len-i; a++) {
                            int g = gcd(tmp, set[a]);
                            tmp /= g;
                            set[a] /= g;
                        }
                    }
                }
                long long tmp = 1;
                for(k = 2; k < len-i; k++)
                    tmp *= set[k];
                ans += tmp;
                cnt[j]++;
            }
            cnt[s[i]-'a']--;
        }
        printf("%10lld\n", ans+1);
    }
    return 0;
}

台長: Morris
人氣(1,177) | 回應(0)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 不分類 | 個人分類: UVA |
此分類下一篇:[UVA] 789 - Indexing
此分類上一篇:[UVA] 10374 - Election

是 (若未登入"個人新聞台帳號"則看不到回覆唷!)
* 請輸入識別碼:
請輸入圖片中算式的結果(可能為0) 
(有*為必填)
TOP
詳全文