(康托展开解释)+ NYOJ 139 我排第几个
描述
現(xiàn)在有"abcdefghijkl”12個(gè)字符,將其所有的排列中按字典序排列,給出任意一種排列,說(shuō)出這個(gè)排列在所有的排列中是第幾小的?
- 輸入
- 第一行有一個(gè)整數(shù)n(0<n<=10000);
隨后有n行,每行是一個(gè)排列; 輸出 - 輸出一個(gè)整數(shù)m,占一行,m表示排列是第幾位; 樣例輸入
-
3 abcdefghijkl hgebkflacdji gfkedhjblcia
樣例輸出 -
1 302715242 260726926
來(lái)源 - [苗棟棟]原創(chuàng) 上傳者
- 苗棟棟
比如·第一位是3 1 2 ,然后·就有比第一位3小的有2個(gè) ,則有2*2!就是 123 132 ? ?213 231.......
按照這種思維有一個(gè)科學(xué)方法:康托展開(kāi)?
先看一下它的公式:X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0!?試試看,能看懂嗎??
X為在這個(gè)排列之前的個(gè)數(shù),最后別忘了加1哦;
n為數(shù)組的長(zhǎng)度;
a[n]是比第一位數(shù)小的個(gè)數(shù),注意這里從0開(kāi)始。(n-1)就不用解釋了吧
理解了就好做了,
最后可以先把1~12的竭誠(chéng)用數(shù)組存起來(lái),然后對(duì)于每一位i,有f[12-i]*t ? ? ? ?t相當(dāng)于a[i],比第i位小的個(gè)數(shù);
參考鏈接:http://blog.csdn.net/zhongkeli/article/details/6966805
代碼如下:
#include<stdio.h>
char s[15];
int n;
int main()
{int f[15]; //存階乘;f[1] = 1;for(int i = 2; i <= 12; i++){f[i] = f[i - 1] * i; //計(jì)算相應(yīng)的階乘}scanf("%d",&n);while(n--){int sum = 0;scanf("%s",s + 1); //這里s+1比較好,第一位是是s[1];for(int i = 1; i <= 12; i++){int t = 0; //統(tǒng)計(jì)i后面的比,,,,,,自己看吧for(int j = i + 1; j <= 12; j++){if(s[i] > s[j]) t++;}sum += f[12 - i] * t; //相當(dāng)于t=a[n]*(n-1)+......... n-1==f[12-i] t==a[n]; }printf("%d\n",sum+1); //別忘了加1}return 0;
}
轉(zhuǎn)載于:https://www.cnblogs.com/zitian246/p/9123560.html
總結(jié)
以上是生活随笔為你收集整理的(康托展开解释)+ NYOJ 139 我排第几个的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 荔浦芋头是哪里的芋头,怎么做好吃?价格多
- 下一篇: CodeForces 获得数据