一个奇怪的问题
查看原帖
一个奇怪的问题
472628
Mandel520楼主2022/2/21 15:00

下面这段程序的大致功能是先建立一个组合数表(杨辉三角), 其中超过 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, 那为什么这个循环还没有终止?

2022/2/21 15:00
加载中...