7-17 求组合数 - 课外练习4(25计3、4班) (pintia.cn)
1.我的代码
#include <iostream>
using namespace std;
int main()
{ double c;
long long m,n;
cin>>m>>n;
long long cha=1;
int n_=1,m_=1;
for(int a=1;a<=n;a++)
{n_=n_*a;}
for(int b=1;b<=m;b++)
{m_=m_*b;}
for(int d=1;d<=n-m;d++)
{cha=cha*d;}
c=n_*1.0/(m_*cha);
cout<<"result = "<<c;
return 0;
}
豆包点评:你的代码在计算组合数 C(n,m) 时,当 m=n/2(即 n=2m)出现错误,很可能是由于整数溢出导致的。
2.想法一:改为longlong
豆包点评:使用 long long 可以缓解整数溢出问题,但无法彻底解决,尤其是当 n 较大时(例如 n≥21),即使改用 long long 仍会溢出。
3.豆包代码
#include <iostream>
using namespace std;
int main() {
int m, n;
cin >> m >> n;
// 确保 m 是较小的那个(组合数对称性:C(n,m)=C(n,n-m))
if (m > n - m) {
m = n - m;
}
double result = 1.0;
for (int i = 1; i <= m; ++i) {
// 逐步计算:分子乘 (n - m + i),分母乘 i,每一步都先乘后除,避免大阶乘,
result = result * (n - m + i) / i;
}
cout << "result = " << result << endl;
return 0;
}
4.question 1
for (int i = 1; i <= m; ++i) { // 逐步计算:分子乘 (n - m + i),分母乘 i,避免大阶乘 result = result * (n - m + i) / i; } 为什么这个可以算组合数


5.question 2
// 确保 m 是较小的那个(组合数对称性:C(n,m)=C(n,n-m)) if (m > n - m) { m = n - m; } 为什么要这一步


最后给看到这里的你送上一张图片


被折叠的 条评论
为什么被折叠?



