我排第幾個
時間限制:1000 ms | 記憶體限制:65535 kb
難度:3
描述
現在有"abcdefghijkl」12個字元,將其所有的排列中按字典序排列,給出任意一種排列,說出這個排列在所有的排列中是第幾小的?
輸入
第一行有乙個整數n(0輸出
輸出乙個整數m,佔一行,m表示排列是第幾位;
樣例輸入3
abcdefghijkl
hgebkflacdji
gfkedhjblcia
樣例輸出1
302715242
260726926
解題思路:
1、 用康托展開,找出第幾個。
康托展開:
1,2,3,4,...,n}表示1,2,3,...,n的排列如 按從小到大排列一共6個。123 132 213 231 312 321 。
代表的數字 1 2 3 4 5 6 也就是把10進製數與乙個排列對應起來。
他們間的對應關係可由康托展開來找到。
如我想知道321是中第幾個大的數可以這樣考慮 :
第一位是3,當第一位的數小於3時,那排列數小於321 如 123、 213 ,小於3的數有1、2 。所以有2*2!個。再看小於第二位2的:小於2的數只有乙個就是1 ,所以有1*1!=1 所以小於321的排列數有2*2!+1*1!=5個。所以321是第6個大的數。 2*2!+1*1!+0*0!就是康托展開。
再舉個例子:1324是排列數中第幾個大的數:第一位是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
#include
int main()
int a[12];
int n,i,j,k,b[12];
char c[15];
a[0]=1;
j=1;
for(i=1;i<12;i++)
j*=i;
a[i]=j; // 把 1~~12的階乘儲存在對應的陣列裡面。
//printf("%d ",a[i]);
while(scanf("%d",&n)!=eof)
memset(b,0,sizeof(b)); //陣列 b 清零。
scanf("%s",c);
for(i=0;i<12;i++)
for(j=i+1;j<12;j++)
if(c[i]>c[j])
b[i]++; // 比後面的字母大的有幾個
k=0;
for(i=0;i<12;i++)
k=k+b[i]*a[11-i]; // 康拓展開。
printf("%d\n",k+1); //輸出結果要加以。
return 0;
139 我排第幾個
時間限制 1000 ms 記憶體限制 65535 kb 難度 3 描述 現在有 abcdefghijkl 12個字元,將其所有的排列中按字典序排列,給出任意一種排列,說出這個排列在所有的排列中是第幾小的?輸入 第一行有乙個整數n 0 輸出輸出乙個整數m,佔一行,m表示排列是第幾位 樣例輸入 3 ab...
我排第幾個?
時間限制 1000 ms 記憶體限制 65535 kb 難度 3 描述 現在有 abcdefghijkl 12個字元,將其所有的排列中按字典序排列,給出任意一種排列,說出這個排列在所有的排列中是第幾小的?輸入 第一行有乙個整數n 0 輸出 輸出乙個整數m,佔一行,m表示排列是第幾位 樣例輸入 3 a...
我排第幾個
時間限制 1000 ms 記憶體限制 65535 kb 難度 3 描述 現在有 abcdefghijkl 12個字元,將其所有的排列中按字典序排列,給出任意一種排列,說出這個排列在所有的排列中是第幾小的?輸入 第一行有乙個整數n 0 輸出輸出乙個整數m,佔一行,m表示排列是第幾位 樣例輸入 3 ab...