求救:求二进制末尾0的个数,哪儿出错了??

越氏羿界 2014-04-17 08:29:00
1021: 组合数末尾的零
时间限制: 1 Sec 内存限制: 128 MB
提交: 118 解决: 76
[提交][状态][讨论版]
题目描述
  从m个不同元素中取出n (n≤ m)个元素的所有组合的个数,叫做从m个不同元素中取出n个元素的组合数。组合数的计算公式如下:
  C(m, n) = m!/((m- n)!n!)
  现在请问,如果将组合数C(m, n)写成二进制数,请问转这个二进制数末尾有多少个零。
输入
  第一行是测试样例的个数T,接下来是T个测试样例,每个测试样例占一行,有两个数,依次是m和n,其中n ≤ m≤ 1000。
输出
  分别输出每一个组合数转换成二进制数后末尾零的数量。
样例输入
2
4 2
1000 500

样例输出
1
6


源代码:
#include<iostream>
using namespace std;

int main ()
{
int m,n;
int c,i,e; //(m- n)!
long _cha=1,cha=1;
int T;
cin >> T ;
for(e=0;e<T;e++)
{
cin >> m >> n ;
for(i=n+1;i<=m;i++) //阶乘
{
_cha=_cha*i;
}
for(i=1;i<=(m-n);i++)
{
cha=cha*i;
}
c=_cha/cha ; //组合数
int yu,sh;
long A=0;
sh=c;
yu=sh%2;
sh=sh/2;
while(yu==0&&sh>=2) //末尾0的数目
{
A++;
yu=sh%2;
sh=sh/2;
}
cout << A << endl ;
}
}
...全文
338 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
越氏羿界 2014-04-18
  • 打赏
  • 举报
回复
连夜问大神,终于调试成功了,灭哈哈哈哈哈哈哈 #include<iostream> using namespace std; int factorial(int m); //函数声明 int main () { int m,n; int a,b,c,e; int T; cin >> T ; for(e=0;e<T;e++) { cin >> m >> n ; a=factorial(m); b=factorial(n); c=factorial(m-n); cout << a-b-c << endl ; //最终结果的0的个数 } return 0; } int factorial(int m) //计算阶乘末尾0的个数 { int a=0,i; for(i=1;i<=m;i++) { int yu,sh; sh=i; yu=sh%2; while(yu==0) { a++; sh=sh/2; yu=sh%2; } } return a; }
赵4老师 2014-04-18
  • 打赏
  • 举报
回复
算100!
越氏羿界 2014-04-18
  • 打赏
  • 举报
回复
引用 5 楼 zhao4zhong1 的回复:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int COMPARE(string number1, string number2) {
    int i,j;

    int length1 = number1.size();
    int length2 = number2.size();

    if(number1.size() == 0) number1 = "0";
    if(number2.size() == 0) number2 = "0";

    j = 0;
    for(i = 0; i < length1; ++i) {
        if(number1[i] == '0') ++j;
        else break;
    }
    number1 = number1.substr(j);

    j = 0;
    for(i = 0; i < length2; ++i) {
        if(number2[i] == '0') ++j;
        else break;
    }
    number2 = number2.substr(j);

    length1 = number1.size();
    length2 = number2.size();

    if(length1 > length2) {
        return 1;
    } else if(length1 == length2) {
        if(number1.compare(number2) > 0) {
            return 1;
        } else if(number1.compare(number2) == 0) {
            return 0;
        } else {
            return -1;
        }
    } else {
        return -1;
    }

    return 0;
}
string PLUS(string number1,string number2) {
    int i;
    int length1 = number1.size();
    int length2 = number2.size();

    string result="";

    reverse(number1.begin(), number1.end());
    reverse(number2.begin(), number2.end());

    for(i = 0; i < length1 && i < length2; i++) {
        char c = (char)(number1[i] + number2[i] - 48);
        result = result + c;
    }

    while(i < length1) {
        result = result + number1[i];
        ++i;
    }

    while(i < length2) {
        result = result + number2[i];
        ++i;
    }

    int carry = 0;
    for(i = 0; i < (int)result.size(); ++i) {
        int value = result[i] - 48 + carry;
        result[i] = (char)(value % 10 + 48);
        carry = value / 10;
    }

    if(carry !=0 ) {
        result = result + (char)(carry + 48);
    }

    for(i = result.size() - 1; i >= 0; i--) {
        if(result[i] != '0') break;
    }

    result = result.substr(0, i + 1);

    reverse(result.begin(), result.end());
    if(result.length() == 0) result = "0";
    return result;
}
string MINUS(string number1,string number2) {
    int i;
    string result = "";

    int length1 = number1.size();
    int length2 = number2.size();

    if(COMPARE(number2,number1) > 0) {
        return "-" + MINUS(number2, number1);
    }

    reverse(number1.begin(),number1.end());
    reverse(number2.begin(),number2.end());

    for(i = 0; i < length1 && i < length2; i++) {
        char c = number1[i] - number2[i] + 48;
        result = result + c;
    }

    if(i < length1) {
        for(; i < length1; i++) {
            result = result + number1[i];
        }
    }

    int carry = 0;
    for(i = 0; i < (int)result.length(); i++) {
        int value = result[i] - 48 + carry;
        if(value < 0) {
            value = value + 10;
            carry = -1;
        } else carry = 0;
        result[i]=(char)(value + 48);
    }

    for(i = result.size() - 1; i >= 0; i--) {
        if(result[i] != '0')break;
    }

    result = result.substr(0, i+1);

    reverse(result.begin(), result.end());
    if(result.length()==0) result = "0";
    return result;
}
string MULTIPLY(string number1, string number2) {
    int i, j;
    int *iresult;
    int length1 = number1.size();
    int length2 = number2.size();
    string result = "";

    reverse(number1.begin(), number1.end());
    reverse(number2.begin(), number2.end());

    iresult = (int*)malloc(sizeof(int) * (length1 + length2 + 1));
    memset(iresult, 0, sizeof(int) * (length1 + length2 + 1));

    for(i = 0; i < length1; i++) {
        for(j = 0; j < length2; j++) {
            iresult[i+j] += ((number1[i] - 48) * (number2[j] - 48));
        }
    }

    int carry = 0;
    for(i = 0; i < length1 + length2; i++) {
        int value = iresult[i] + carry;
        iresult[i] = value % 10;
        carry = value / 10;
    }

    for(i = length1 + length2 - 1; i >= 0; i--) {
        if(iresult[i] != 0)break;
    }

    for(; i >= 0; i--) {
        result = result + (char)(iresult[i]+48);
    }

    free(iresult);

    if(result == "") result = "0";
    return result;
}
string factorial(string n) {
    string temp = "1";
    string i;
    for(i = "1"; COMPARE(i, n) <= 0; i = PLUS(i, "1")) {
        temp = MULTIPLY(temp, i);
    }
    return temp;
}
int main(void) {
    cout << factorial("100") << endl;
    return 0;
}
这是??? 输出都是很长的一组数。。。。
越氏羿界 2014-04-18
  • 打赏
  • 举报
回复
引用 2 楼 FancyMouse 的回复:
不去算质因子个数想直接算阶乘/组合数的值,这太耍流氓了(
对不起,新手。扔错板砖了。不过,您说的是什么意思???有点不懂。。。
FancyMouse 2014-04-18
  • 打赏
  • 举报
回复
引用 3 楼 nice_cxf 的回复:
不就是最后结果能整除的最大的2^n的n么?
我错了……题目说二进制那的确只用2^n就行。
赵4老师 2014-04-18
  • 打赏
  • 举报
回复
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int COMPARE(string number1, string number2) {
    int i,j;

    int length1 = number1.size();
    int length2 = number2.size();

    if(number1.size() == 0) number1 = "0";
    if(number2.size() == 0) number2 = "0";

    j = 0;
    for(i = 0; i < length1; ++i) {
        if(number1[i] == '0') ++j;
        else break;
    }
    number1 = number1.substr(j);

    j = 0;
    for(i = 0; i < length2; ++i) {
        if(number2[i] == '0') ++j;
        else break;
    }
    number2 = number2.substr(j);

    length1 = number1.size();
    length2 = number2.size();

    if(length1 > length2) {
        return 1;
    } else if(length1 == length2) {
        if(number1.compare(number2) > 0) {
            return 1;
        } else if(number1.compare(number2) == 0) {
            return 0;
        } else {
            return -1;
        }
    } else {
        return -1;
    }

    return 0;
}
string PLUS(string number1,string number2) {
    int i;
    int length1 = number1.size();
    int length2 = number2.size();

    string result="";

    reverse(number1.begin(), number1.end());
    reverse(number2.begin(), number2.end());

    for(i = 0; i < length1 && i < length2; i++) {
        char c = (char)(number1[i] + number2[i] - 48);
        result = result + c;
    }

    while(i < length1) {
        result = result + number1[i];
        ++i;
    }

    while(i < length2) {
        result = result + number2[i];
        ++i;
    }

    int carry = 0;
    for(i = 0; i < (int)result.size(); ++i) {
        int value = result[i] - 48 + carry;
        result[i] = (char)(value % 10 + 48);
        carry = value / 10;
    }

    if(carry !=0 ) {
        result = result + (char)(carry + 48);
    }

    for(i = result.size() - 1; i >= 0; i--) {
        if(result[i] != '0') break;
    }

    result = result.substr(0, i + 1);

    reverse(result.begin(), result.end());
    if(result.length() == 0) result = "0";
    return result;
}
string MINUS(string number1,string number2) {
    int i;
    string result = "";

    int length1 = number1.size();
    int length2 = number2.size();

    if(COMPARE(number2,number1) > 0) {
        return "-" + MINUS(number2, number1);
    }

    reverse(number1.begin(),number1.end());
    reverse(number2.begin(),number2.end());

    for(i = 0; i < length1 && i < length2; i++) {
        char c = number1[i] - number2[i] + 48;
        result = result + c;
    }

    if(i < length1) {
        for(; i < length1; i++) {
            result = result + number1[i];
        }
    }

    int carry = 0;
    for(i = 0; i < (int)result.length(); i++) {
        int value = result[i] - 48 + carry;
        if(value < 0) {
            value = value + 10;
            carry = -1;
        } else carry = 0;
        result[i]=(char)(value + 48);
    }

    for(i = result.size() - 1; i >= 0; i--) {
        if(result[i] != '0')break;
    }

    result = result.substr(0, i+1);

    reverse(result.begin(), result.end());
    if(result.length()==0) result = "0";
    return result;
}
string MULTIPLY(string number1, string number2) {
    int i, j;
    int *iresult;
    int length1 = number1.size();
    int length2 = number2.size();
    string result = "";

    reverse(number1.begin(), number1.end());
    reverse(number2.begin(), number2.end());

    iresult = (int*)malloc(sizeof(int) * (length1 + length2 + 1));
    memset(iresult, 0, sizeof(int) * (length1 + length2 + 1));

    for(i = 0; i < length1; i++) {
        for(j = 0; j < length2; j++) {
            iresult[i+j] += ((number1[i] - 48) * (number2[j] - 48));
        }
    }

    int carry = 0;
    for(i = 0; i < length1 + length2; i++) {
        int value = iresult[i] + carry;
        iresult[i] = value % 10;
        carry = value / 10;
    }

    for(i = length1 + length2 - 1; i >= 0; i--) {
        if(iresult[i] != 0)break;
    }

    for(; i >= 0; i--) {
        result = result + (char)(iresult[i]+48);
    }

    free(iresult);

    if(result == "") result = "0";
    return result;
}
string factorial(string n) {
    string temp = "1";
    string i;
    for(i = "1"; COMPARE(i, n) <= 0; i = PLUS(i, "1")) {
        temp = MULTIPLY(temp, i);
    }
    return temp;
}
int main(void) {
    cout << factorial("100") << endl;
    return 0;
}
FancyMouse 2014-04-18
  • 打赏
  • 举报
回复
引用 3 楼 nice_cxf 的回复:
不就是最后结果能整除的最大的2^n的n么?
2^n和5^n两种情况的min。
nice_cxf 2014-04-18
  • 打赏
  • 举报
回复
不就是最后结果能整除的最大的2^n的n么?
FancyMouse 2014-04-18
  • 打赏
  • 举报
回复
不去算质因子个数想直接算阶乘/组合数的值,这太耍流氓了(
Gonefar 2014-04-17
  • 打赏
  • 举报
回复
10000的阶乘long型都会溢出吧。你应该是某些测试点没过把

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧