1. 程式人生 > >計算機考研真題 排列與二進位制

計算機考研真題 排列與二進位制

題目描述

在組合數學中,我們學過排列數。從n個不同元素中取出m(m<=n)個元素的所有排列的個數,叫做從n中取m的排列數,記為p(n, m)。具體計算方法為p(n, m)=n(n-1)(n-2)……(n-m+1)= n!/(n-m)! (規定0!=1).當n和m不是很小時,這個排列數是比較大的數值,比如  p(10,5)=30240。如果用二進位制表示為p(10,5)=30240=( 111011000100000)b,也就是說,最後面有5個零。我們的問題就是,給定一個排列數,算出其二進位制表示的後面有多少個連續的零。

輸入描述:

輸入包含多組測試資料,每組測試資料一行。
每行兩個整數,n和m,0<m<=n<=10000,n=0標誌輸入結束,該組資料不用處理。

輸出描述:

對於每個輸入,輸出排列數p(n, m)的二進位制表示後面有多少個連續的零。每個輸出放在一行。
示例1

輸入

10 5
6 1
0 0

輸出

5
1





//計算機考研真題 排列與二進位制
/*
程式設計思想:
    問題實質就是求n*(n-1)*……*(n-m+1)能整除幾次2。那麼,可以把每個乘數分別判其斷能分解出的2的數量,
然後加在一起就是乘積能分解出的2的數量。
*/ //程式實現: #include<iostream> using namespace std; const int N=10001; int main(){ int two[N]={0}; ///two[i]表示i能分解出2的個數 int tmp=0; for(int i=1;i<N;++i){ //求1到N中每個數能分解出2的個數 tmp=i; while(tmp%2==0){ tmp=tmp/2; two[i]++; } }
int n=0,m=0,cnt=0; //cnt一定要初始化,這是教訓,因為累積過程中,第一次會給隨機值!以後變數都初始化! while(cin>>n>>m&&n!=0){ for(int i=n; i>n-m;--i) //統計 cnt+=two[i]; cout<<cnt<<endl; } return 0; }