向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时数学方法应该是正确的吧,变成负数说明数太大装不下了,而第一种方法还能显出一个整数?











。