時間限制:
1000 ms | 記憶體限制:
65535 kb
難度: 3
描述 現在有"abcdefghijkl」12個字元,將其所有的排列中按字典序排列,給出任意一種排列,說出這個排列在所有的排列中是第幾小的?
輸入
第一行有乙個整數n(0
輸出輸出乙個整數m,佔一行,m表示排列是第幾位;
樣例輸入
3abcdefghijkl
hgebkflacdji
gfkedhjblcia
樣例輸出
1302715242
260726926
康托展開:
康托展開康托展開就是一種特殊的雜湊函式,它的使用範圍是對於n個數的排列進行狀態的壓縮和儲存,例如要對9的全排列進行判重.沒有必要
開乙個10^9的陣列,同時記憶體也不允許開到那麼大的陣列.對此,有人提出了優化,即對於乙個n的排列數,沒有必要開到10^n,因為在乙個排列中每個數隻出現一次,所以只要前n-1位確定了,前n位就確定了.
但是以上的想法仍不是可行的,因為n可以很大,例如15,所以便引入了康托展開:只需要確定這個排列在總的排列情況中是第幾小的就可以了.
例如:我想知道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!是康托展開.
下面給出康托展開的**:
int
hash(s[12])
return
ktzk;
}
#include#include#includeusing namespace std;
int a[12]= ;//記錄0,1,2,3,4,5,6,7,8,9,10,11的階乘
char b[1000];
int c[1000];
int main()
}sum+=p*a[i];
}printf("%d\n",sum+1);
}}
我排第幾個?
時間限制 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...
我排第幾個
時間限制 1000 ms 記憶體限制 65535 kb 難度 3 描述 現在有 abcdefghijkl 12個字元,將其所有的排列中按字典序排列,給出任意一種排列,說出這個排列在所有的排列中是第幾小的?輸入 第一行有乙個整數n 0 輸出輸出乙個整數m,佔一行,m表示排列是第幾位 樣例輸入 3 ab...