向beyondyf大哥请教,并和大家一起研究。
下面是我给出的一道题:大家一起来做题:二维数组取数求和。给力--->给分!
输入一个n行m列(2 <= n <= 16 , 2 <= m <= 24)二维数组,每行的元素值都是0 1 2 3 …… m -1;要求从每一行取一个元素,使取得的n个元素的和等于m-1.问有多少种取法,并打印出每种取法对应的n个元素。
比如 3 * 4 的二维数组a 0 1 2 3
0 1 2 3
0 1 2 3
取数使a[0][?] + a[1][?] + a[2][?] = 3 有多少种取法,及其对应的3个数。取法数太大的可以不用打印对应元素。
连接是:https://bbs.bccn.net/thread-359913-1-1.html
杨大哥给了代码我贴上来,并请教几个问题(为了测试数据,我改了下范围和循环,核心没动)。
程序代码:
#include #include #define N_MAX 100 #define M_MAX 100 __int64 a[N_MAX + 1][M_MAX]; void init() { int i, j; for(i = 1; i <= N_MAX; i++) for(j = 1; j < M_MAX; j++) a[i][j] = a[i][j - 1] + a[i - 1][j] + 1; for(i = N_MAX; i; i--) for(j = M_MAX - 1; j; j--) a[i][j] -= a[i][j - 1]; } __int64 cal(int n, int m) { if(n <= 0 || m <= 0) return 0; if(n == 1) return m; if(m == 1) return n; return cal(n, m - 1) + cal(n - 1, m) + 1; } __int64 c(int n, int m) { __int64 r; int i; for(r = i = 1; i < n; i++) { r *= m - 1 + i; r /= i; } return r; } void print(int n, int m, int index) { int i; static int list[N_MAX]; if(n <= 1) { for(i = 0; i < index; printf("%d ", list[i++])); printf("%d\n", m); return; } for(list[index] = i = 0; i <= m; list[index] = ++i) print(n - 1, m - i, index + 1); } int main() { int n, m; int start, end; while(1) { init(); printf("Please input n & m:"); scanf("%d %d", &n, &m); if(a[n][m - 1] <= 10000) print(n, m - 1, 0); else printf("it's too large.\n"); printf("The methods count is %I64d\n", a[n][m - 1]); printf("The mothods count is %I64d\n", c(n, m)); if (n <= 16 && m <= 21) { start = clock(); printf("The methods count is %I64d\n", cal(n, m - 1) - cal(n, m - 2)); end = clock(); printf("time is :%-3dsecond!\n",(end - start)/CLK_TCK); } } return 0; }上面题供了3种放法.一时难以领会,特别是打印函数,print(n, m - 1, 0); 为什么index传入的是0,而在整个
print函数中index自身貌似没发生变化,那么for(i = 0; i < index; printf("%d ", list[i++]));这个句能循环起来吗?
下面是我的测试数据:
为什么输入1 1时3个函数中有个不一样,输入到 32 32时数学方法应该是正确的吧,变成负数说明数太大装不下了,而第一种方法还能显出一个整数?