POJ - 1850 Code(排列組合)
Transmitting and memorizing information is a task that requires different coding systems for the best use of the available space. A well known system is that one where a number is associated to a character sequence. It is considered that the words are made only of small characters of the English alphabet a,b,c, …, z (26 characters). From all these words we consider only those whose letters are in lexigraphical order (each character is smaller than the next character).
The coding system works like this:
• The words are arranged in the increasing order of their length.
• The words with the same length are arranged in lexicographical order (the order from the dictionary).
• We codify these words by their numbering, starting with a, as follows:
a - 1
b - 2
…
z - 26
ab - 27
…
az - 51
bc - 52
…
vwxyz - 83681
…
Specify for a given word if it can be codified according to this coding system. For the affirmative case specify its code.
Input
The only line contains a word. There are some constraints:
• The word is maximum 10 letters length
• The English alphabet has 26 characters.
Output
The output will contain the code of the given word, or 0 if the word can not be codified.
Sample Input
bf
Sample Output
55
題目連結
參考題解1
參考題解2
這個題目求這個字串的位序,其實就是求他前面的個數加一,並且輸入的字串都應該是嚴格遞增的序列。先求 len<x的字串數量,再求len==x,比當前字串小的數量,只要選出一定的字母,那麼他們的順序就一定確定下來了,接下來就是找排列數的問題了。首先對楊輝三角預處理了一下,後面就是做數學題了。
#include <cstdio>
#include <cstring>
#define LL long long
using namespace std;
LL inf = 15;
LL n, m;
char tm[15];
LL c[30][30];
//預處理工作,儲存楊輝三角所有值
void pre()
{
LL i, j;
for (i = 0; i <= 26; i++)
c[i][0] = 1;
for (i = 1; i <= 26; i++)
for(j = 1; j <= i; j++)
c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]);
}
//檢驗字元是否合法,要單調增
int check(char *s, int len)
{
for (int i = 1; i < len; i++)
{
if (s[i] <= s[i - 1]) return 0;
}
return 1;
}
int main()
{
pre();
scanf("%s", tm);
int len = strlen(tm);
int ret = check(tm, len);
if (!ret)
{
printf("0\n");
return 0;
}
LL sum = 0, i, j;
for (i = 1; i < len; i++)//累計所有長度小於len的字串個數
sum += c[26][i];
//接下來算長度等於len的字串個數
if (tm[0] > 'a')
{
LL tmp = 0;
for (i = 1; i <= tm[0] - 'a' - 1 + 1; i++) //tm[0]-'a'+1得到該字母對應數字,減一表示按照嚴格遞增
tmp += c[26 - i][len - 1];
sum += tmp;
}
for (i = 1; i < len; i++)
{
if (tm[i] - 1 - tm[i - 1] > 0)
{
LL tmp = 0;
for (j = tm[i - 1] - 'a' + 1 + 1; j <= tm[i] - 'a' + 1 - 1; j++) //tm[i-1]-'a'+1得到該字母對應數字,加一表示按照嚴格遞增,不與i-1個字元重複,其他同理
tmp += c[26 - j][len - i - 1];
sum += tmp;
}
}
printf("%lld\n", sum+1);
return 0;
}