下面这段程序的大致功能是先建立一个组合数表(杨辉三角), 其中超过 k 的结果对 k 取模.
然后给定一组 i, j 查找符合条件(正好是 k 的倍数)的组合数的个数
#include<stdio.h>
#define MIN(A,B) (A<B)?A:B
int n, m;
int t, k;
long long C[2005][2005];
void comb_nums(int x){ //计算从0~x的组合数
for (int i = 0; i <= x; i++){
C[i][0] = C[i][i] = 1;
for (int j = 1; j < i; j++){ //在x个数中取0~x个数
C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % k; //递推(别忘了取模)
}
}
}
int main(){
scanf("%d %d", &t, &k);
comb_nums(2000); //建立杨辉三角
while(t--){
int ans = 0; //符合题意的组合数个数
scanf("%d %d", &n, &m);
for (int i = 0; i <= n; i++){
for (int j = 0; j <= MIN(i, m); j++){
//printf("%d %d\n", j, MIN(i, m));
if (!C[i][j]) ans++; //统计符合题意的组合数个数
}
}
printf("%d\n", ans);
}
return 0;
}
现在问题来了, main()函数中的 if (!C[i][j]) ans++;语句, 只要一运行它就会触发段错误(数组下标越界). 我查看调试器, 发现数组越界的原因是变量 j 变成了一个超大值
将上一行的printf("%d %d\n", j, MIN(i, m));语句取消注释, 查看结果, 如下所示:
.........
36476 1
36477 1
36478 1
36479 1
36480 1
36481 1
36482 1
36483 1
36484 1
36485 1
36486 1
36487 1
36488 1
36489 1
36490 1
36491 1
36492 1
.........
于是我感到疑惑, 既然 for 循环中规定j <= MIN(i, m), 现在 j 都涨到三万多了, MIN(i, m)还是 1, 那为什么这个循环还没有终止?