首页 新闻 会员 周边 捐助

a+b+c+d=10,怎么找出所有可能?求教

0
悬赏园豆:10 [待解决问题]

如题,abcd都是int,取值范围已知但不尽相同,怎么找出满足条件的所有可能啊?除了采取for循环去遍历之外有没有其他方法,题目是4个数,要是数字有n个呢?怎么处理,谢谢

夫人的老公的主页 夫人的老公 | 初学一级 | 园豆:200
提问于:2011-12-02 14:46
< >
分享
所有回答(3)
0

写个循环就行了。

public int GetValue()

{

int sum=0;

for(int a=0;a<11;a++)

{

for(int b=0;b<11;b++)

{

for(int c=0;c<11;c++)

{

for(int d=0;d<11;d++)

{

int num=a+b+c+d;

if(num==10)

{

sum+=1;

}

}

}

}

}

return sum;

}

sunlary | 园豆:934 (小虾三级) | 2011-12-02 15:01

兄弟,你这只是计算出了满足条件的可能性的个数,而且不怎么关心这,我意思是除了用for循环一层层的套,还能用其他方法吗?如果是100个数相加,你这个方法就不好使了

支持(0) 反对(0) 夫人的老公 | 园豆:200 (初学一级) | 2011-12-02 15:15
1
static Stack<int> current = new Stack<int>();
static List<int[]> all = new List<int[]>();

static void Main(string[] args)
{
int n = 4;
int number = 10
    Process(1, number, n);    
    foreach (var answer in all)
{
Console.WriteLine(string.Join(",", answer));
}
Console.Read();
}

static void Process(int start, int remainingNumber, int remainingN)
{
int max = remainingNumber / remainingN;
for (int i = start; i <= max; i++)
{
if (remainingN == 1)
{
current.Push(remainingNumber);
all.Add(current.Reverse().ToArray());
current.Pop();
break;
}
else
{
current.Push(i);
Process(i, remainingNumber - i, remainingN - 1);
current.Pop();
}
}
}

代码写的仓促,可以调整下结构。

水牛刀刀 | 园豆:6350 (大侠五级) | 2011-12-02 15:32

好思路,不过存在几个漏洞。

        static Stack<int> current = new Stack<int>();
static List<int[]> all = new List<int[]>();

static void Main(string[] args)
{
int varCount = 4;
int startValue = 1;
int number = 10;

// 在 进入Process之间进行输入参数合法性检查,也可以在Process内部进行检查,但在这里效率更高
if ((number - varCount * startValue) < 0)
{
Console.WriteLine("输入参数错误!");
return;
}
Process(startValue, number, varCount);
foreach (var answer in all)
{
Console.WriteLine(string.Join(",", answer));
}
Console.Read();
}

static void Process(int start, int remainingNumber, int remainingN)
{
// 存在逻辑错误
// int max = remainingNumber / remainingN;
int max = remainingNumber - (remainingN - 1) * start;

for (int i = start; i <= max; i++)
{
if (remainingN == 1)
{
current.Push(remainingNumber);
all.Add(current.Reverse().ToArray());
current.Pop();
break;
}
else
{
current.Push(i);
Process(i, remainingNumber - i, remainingN - 1);
current.Pop();
}
}
}



支持(0) 反对(0) 胡屯 | 园豆:714 (小虾三级) | 2011-12-03 12:04

@胡屯: 懒得写检查了。只提供大体思路而已。

支持(0) 反对(0) 水牛刀刀 | 园豆:6350 (大侠五级) | 2011-12-03 15:05

@胡屯: int max = remainingNumber / remainingN; 才是对的。你再仔细想想。

支持(0) 反对(0) 水牛刀刀 | 园豆:6350 (大侠五级) | 2011-12-03 15:06

@胡屯: 

static Stack<int> current = new Stack<int>();
static List<int[]> all = new List<int[]>();
是什么东西啊?

我是学C的

支持(0) 反对(0) 夫人的老公 | 园豆:200 (初学一级) | 2011-12-06 09:43

@夫人的老公: ....C的话,你就得自己实现一个栈了……算了我懒的写了,反正我算法提供了。

支持(0) 反对(0) 水牛刀刀 | 园豆:6350 (大侠五级) | 2011-12-06 10:05
0
//实际上,这个题目如果只是4个,那么非常的简单,直接用for。
//但是循环的时候,加个限制,计算数目的速度就非常的快。

#include <stdio.h>

int main()
{
int a, b, c, d;
int sum = 1000;
long long total = 0;
for (a = 0; a <= sum; a++)
{
for (b = 0; b <= (sum - a); b++)
{
for (c = 0; c <= (sum - a - b); c++)
{
d = sum - a - b -c;
if (d >= 0) {
total++;
//printf("%d %d %d %d\n", a, b, c, d);
} else {
break;
}
}
}
}
printf("%ld\n", total);
}

如果从一般的角度看这个问题,这个问题其实是非常著名的一个问题,多重集合排列数的问题。你可以看看组合数学的书本。一般的公式为:C(r+k-1, r) r就是求和的数目,k就是参数的个数。C就是组合数,比如r = 10, k = 4 的情况下的结果是

http://www.wolframalpha.com/input/?i=C%2813%2C+10%29  (286)

如果说是通用的,k不限制的情况,可以用一个循环改递归的技巧,很容易改过来。

多重循环改递归应该会的吧,会的话,我就不写这个递归版本的代码了。

暮夏 | 园豆:391 (菜鸟二级) | 2011-12-07 14:29
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册