输入包含多组测试数据,每组测试数据一行。 每行两个整数,n和m,0<m<=n<=10000,n=0标志输入结束,该组数据不用处理。
对于每个输入,输出排列数p(n, m)的二进制表示后面有多少个连续的零。每个输出放在一行。
10 5 6 1 0 0
5 1
0×0=0
0×1=1×0=0
1×1=1
例如:1001和1010相乘的过程如下:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in=new Scanner(System.in); while(in.hasNextInt()) { int n=in.nextInt(); int m=in.nextInt(); if(n==0) break; int res=0; for(int i=n-m+1;i<=n;++i) { int tmp=i; while((tmp&1)==0) { ++res; tmp>>=1; } } System.out.println(res); } in.close(); } }
//就是n-m+1-----n这一堆数中能整除2多少次 #include<stdio.h> (737)#include<math.h> int main() { int m,n,i,k,num; while(scanf("%d%d",&n,&m)!=EOF) { if(n==0&&n==m) break; num=0; for(i=n-m+1;i<=n;i++)//所有的数 { k=i; while(k%2==0)//这个数能整除2 { num++; k=k/2; } } printf("%d\n",num); } return 0; }
#include <bits/stdc++.h> using namespace std; string tmp; char BignumberMod(string s){ int mod=0; tmp=""; for(int i=0;i<s.size();i++){ mod=mod*10+s[i]-'0'; if((i!=s.size()-1)){ if(mod<2) { if(i==0) continue; tmp.push_back('0'); continue; } } tmp.push_back((char)(mod/2+'0')); mod=mod%2; if(i==s.size()-1){ return (char)(mod+'0'); } } } int GetBits(string s) { string result; int count=0; // if(s.size()==1&&s[0]=='0') { // cout<<0<<endl; // continue; // } // result.clear(); while(s.size()>=1){ // if(s.size()==1&&stoi(s)==0) break;//巧用短路性 if(BignumberMod(s)=='0') count++; else break; s.assign(tmp); // cout<<s<<endl; } return count; } string addBigNumber(string str1,string str2 ){ int output[100000]; int m=str1.size()-1; int n=str2.size()-1; string result; //cout<<m<<" "<<n; memset(output,0,sizeof(output)); for(int i=0;i<=m;i++){ output[i]=output[i]+(str1[m-i]-'0'); } // for(int i=0;i<=m;i++){ // cout<<output[i]; // } for(int i=0;i<=n;i++){ int sum=output[i]+(str2[n-i]-'0'); // for(int i=0;i<=m;i++){ // cout<<output[i]; // } //cout<<sum<<endl; output[i]=sum%10; if(sum>=10) output[i+1]++; } int size=max(n,m)+1; int flag=0; //cout<<size; for(int i=size;i>=0;i--){ if(flag==0&&output[i]!=0){ flag=1; } if(flag) result.push_back(output[i]+'0'); } reverse(result.begin(),result.end()); return result; } string Bignumbermultiply(string str1,string str2){ string result1,result2; //cin>>str1>>str2; int carry=0; int i=str1.size()-1; int j=str2.size()-1; // cout<<i<<" "<<j<<endl; if(j!=-1){ while(i>=0){ int sum=(str1[i]-'0')*(str2[j]-'0')+carry ; result1.push_back(sum%10+'0'); if(sum>=10) carry=(sum/10)%10; else carry=0; i--; } if(i==-1&&carry!=0) result1.push_back(carry+'0'); } //cout<<result1<<" "<<result2<<endl; j--; if(j==-1){ reverse(result1.begin(),result1.end()); //cout<<result1; return result1; } while(j!=-1){ if(j!=-1){ int k=str2.size()-1-j; while(k--) result2.push_back('0'); i=str1.size()-1; carry=0; while(i>=0){ int sum=(str1[i]-'0')*(str2[j]-'0')+carry ; result2.push_back(sum%10+'0'); if(sum>=10) carry=(sum/10)%10; else carry=0; i--; } if(i==-1&&carry!=0) result2.push_back(carry+'0'); } reverse(result1.begin(),result1.end()); reverse(result2.begin(),result2.end()); //cout<<result1<<" "<<result2<<endl; //cout<<addBigNumber(result1,result2); result1=addBigNumber(result1,result2); result2=""; j--; } reverse(result1.begin(),result1.end()); return result1; } string Getstringnum(int a){ string result; while(a!=0){ result.push_back((a%10)+'0'); a/=10; } reverse(result.begin(),result.end()); return result; } int main(){ int n,m; while(cin>>n>>m&&n!=0){ string l="1"; int count=0; for(int i=1;i<=m;i++){ //cout<<l<<" "<<Getstringnum(n-i+1)<<endl; l=Bignumbermultiply(l,Getstringnum(n-i+1)); } // cout<<Bignumbermultiply("10",Getstringnum(9)); //cout<<Getstringnum(9); cout<<GetBits(l)<<endl; // for(int i=0;;i++){ // if(!GetBits(l,i)) count++; // else break; // } // cout<<count<<endl; } return 0; }
可能我最菜了,心塞
package com.speical.first;
import java.util.Scanner;
/**
*
* @author special
* @date 2018年2月2日 上午9:08:30
*/
public class Pro173 {
static final int MOD = 10000;
public static int[] factory(int n, int m){
int[] result = new int[100000];
int index = 1, carry = 0, temp;
result[index++] = 1;
result[0]++;
for(int i = m; i <= n; i++){
carry = 0;
for(int j = 1; j < index; j++){
temp = i * result[j] + carry;
result[j] = temp % MOD;
carry = temp / MOD;
}
if(carry > 0){
result[index++] = carry;
result[0]++;
}
}
return result;
}
public static int getBinary(int[] num){
int length = num[0], r = 0, count = 0;
for(int i = length; i > 0;){
r = 0;
for(int j = i; j > 0; j--){
num[j] += r * MOD;
r = num[j] % 2;
num[j] /= 2;
}
while(i > 0 && num[i] == 0){
i--;
}
if(r != 0){
break;
}else{
count++;
}
}
return count;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
while(input.hasNext()){
int n = input.nextInt();
int m = input.nextInt();
if(n == 0) break;
int[] result = factory(n, n - m + 1);
System.out.println(getBinary(result));
}
}
}
#include <stdio.h> #define N 10001 int main() { int m, n, x; int count; int a[N];//a[i]表示i能分解出几个2 for(int i=1; i<N; i++) { a[i]=0; x=i; while(x%2==0) { x=x/2; a[i]++; } } while(scanf("%d %d", &n, &m)!=EOF) { if(n==0) break; count=0; for(int i=n; i>n-m; i--) { count+=a[i]; } printf("%d\n", count); } return 0; }
//归根结底就是求出n*(n-1)*...*(n-m+1)一共有多少个2 //所以就每个都除以2直到不为2的倍数为止,也防止乘数过大超出范围 #include<iostream> using namespace std; int main(){ int n,m; while(cin>>n>>m){ if(n==0) break; int begin=n,end=n-m+1,count=0; for(int i=begin;i>=end;i--){ int temp=i; while(temp%2==0){ count++; temp/=2; } } cout<<count<<endl; } }
//此题是不能硬按照公式算的。树打了,就会超出计算机的表示范围。他是有思路的。比如一个是十进制数220,它的末尾有一个连续的0,它本身就相当于22*10,即22扩大10倍,即22左移一位,低位补0。因此对于十进制数而言,想知道末尾有多少个连续的0,实质就是去看这个数含有多少个因子10。比如上面220=22*10,其中22虽然比10大,但它没法再分成关于10的因式了,所以只有一个因子10,即末尾含有一个连续的0。而300=3*10*10,含2个因子10,所以末尾有两个连续的0。 //而同理,对于二进制数据而言,它每一次左移一位,低位补0,就相当于它对于的十进制数乘2。所以一个二进制数据末尾有多少个连续的0,就看它左移了多少次,即它的十进制数据含有多少个因子2。 //另外若A=B*C,那么 A中含因子2的个数 = B中含因子2的个数 + C中含因子2的个数,这个不难理解。比如24=4*6=(2*2)*(2*3)=2*2*2*3。 //所以此题我们只需要分别判断n,n-1,n-2,,,,,,n-m+1中分别有多少个因子2,然后把个数加起来就可以了。 #include <iostream> #include <bitset> using namespace std; int CU(int x) { int s=0; while(x%2==0) { s++; x=x/2; } return s; } int main() { int n, m; while (cin >> n >> m) { if (n == 0) break; int sum=0; for(int i=n-m+1;i<=n;i++) sum+=CU(i); cout<<sum<<endl; } }
#include<iostream> #include<stdio.h> using namespace std; int main() { int n,m,a,p; while(scanf("%d %d",&n,&m)!=EOF&n!=0&m!=0) { a=0; p=1; for(int i=n-m+1;i<=n;++i) { p=i; for(int j=0;j<10000;++j) { if(p%2==0) { a++; p/=2; } else break; } } printf("%d\n",a); } }
#include<iostream> #include<cmath> using namespace std; int main(){ int n,m; while(cin>>n>>m){ int arr[m];int sum=0; for(int i=0;i<m;i++) arr[i]=i+n-m+1; for(int j=0;j<m;j++) for(int k=13;k>=1;k--){ int b=pow(2,k); if(arr[j]%b==0){ sum+=k;break;} } printf("%d\n",sum); } }
#include<iostream> using namespace std; int main() { int n,m,count; while(cin >> n >> m && n && m) { count = 0; int t = 1; for(int i = n;i > n - m;i--) { t *= i; while(t % 2 == 0) { t /= 2; count++; } } cout << count << endl; } return 0; }
#include<iostream> using namespace std; #define max 10001 //二进制表示,算术左移即为乘2,右边补0; //只需右移即除2,找到第一个二进制位为1的就行,右移次数即为0的个数 int main(void) { int m,n; int count = 0; while(cin >> n >> m) { if(n == 0) break; else if(n < max || m < max) { for(int i = n - m + 1;i <= n;i++) { int temp = i; while(temp % 2 == 0) { count++; temp /= 2; } } cout << count << endl; } } return 0; }
#include<iostream> using namespace std; int two(int x){ x = x & (-x); int cnt = 0; while(x>0){ if(!(x&1==1)) cnt++; x = x >> 1; } return cnt; } int main(){ int n,m; while(cin >> n >> m){ if(n==0) return 0; else { int sum = 0 ; for(int i=n;i>=n-m+1;i--){ sum += two(i); } printf("%d\n",sum); } } return 0; }
#include <iostream> using namespace std; int fact(int n){ int counts = 0; while(n != 0){ counts += n / 2; n /= 2; } return counts; } int main() { int x, y; while(cin >> x >> y){ if(x == 0 && y == 0){ break; } cout<<fact(x) - fact(x - y)<<endl; } return 0; }