1. 程式人生 > >poj1496 Word Index / poj1850 Code(組合數學)

poj1496 Word Index / poj1850 Code(組合數學)

poj1850 Code

題意:輸出若干個給定的字串($length<=10$)在字典序中的位置,字串中的字母必須嚴格遞增。

讀取到非法字串時,輸出“0”,終止程式。(poj1496:繼續讀取)

我們分成2種情況討論字典序小於給定字串的字串個數

1.長度比給定字串小

其實長度為$i$的字串的個數就是$C(26,i)$

因為我們隨機選取$i$個字元後,從小到大依次取出,是可以保證字串是有序的。

2.長度等於給定字串

我們列舉每一位,計算從該位開始小於給定字串的個數,同樣可以用組合數計算。

預處理組合數一下........

 1 #include<iostream>
 2
#include<cstdio> 3 #include<cstring> 4 #define re register 5 using namespace std; 6 char a[20]; 7 int C[30][30]; 8 int main(){ 9 for(int i=1;i<=26;++i) 10 for(int j=0;j<=i;++j)//組合數預處理 11 C[i][j]=(!j||i==j)?1:C[i-1][j]+C[i-1][j-1]; 12 while(cin>>a){//
用scanf就OLE(大霧) 13 int len=strlen(a),ans=1; bool flag=0; 14 for(int i=1;i<len;++i) 15 if(a[i]<=a[i-1]){ 16 printf("0\n"); 17 flag=1; break; 18 } 19 if(flag) continue;//1850改為return 0; 20 for(int i=1;i<len;++i) ans+=C[26
][i];//長度<len 21 for(int i=0;i<len;++i){//長度==len,字典序排名在給定串前,列舉每一位 22 for(char ch=i?a[i-1]+1:'a';ch<a[i];++ch)//列舉每個小於a[i]的字母 23 ans+=C['z'-ch][len-i-1]; 24 }printf("%d\n",ans); 25 }return 0; 26 }
poj1496/poj1850 Code