一个c++算法问题。大家来做啊

漁_夫 2009-04-28 11:32:46
请教各位高手一下,1到15之间任意五个数相加的结果为42,不能出现重复!
这个程序怎么写啊……

...全文
342 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
ropel 2009-05-05
  • 打赏
  • 举报
回复
learn
koulongfei 2009-05-05
  • 打赏
  • 举报
回复
也是用for循环,减少了冗余循环长度
#include <stdio.h> 
#include <string.h>
int main()
{
int a,b,c,d,e;
for(a=1;a <=6;a++) // [42-(1+2+3+4)]/5=6.4 取 6
for(b=a+1;b <=8;b++) // [(42-1)-(1+2+3)]/4=8.75 取 8
for(c=b+1;c <=12;c++) // [(42-1-2)-(1+2)]/3=12 取 12
for(d=c+1;d <=14;d++) // [(42-1-2-3)-1]/2=17.5 先判断下一行代码--然后,此行取 (15-1)=14
for(e=d+1;e <=15;e++) // [(42-1-2-3-4)-0]/1=32 取最大数 15
if(a+b+c+d+e==42)
printf("%d %d %d %d %d\n",a,b,c,d,e); // 共137个
return 0;
}


声明:这是我同学张勋提出的,由我执笔回复。
beyond071 2009-04-29
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 yinlijun2001 的回复:]
int dump(int number,int maxno ,int count)
{
if (number>count || (number==1&&count>maxno))
{
return 0;
}

if (number==1)
{
return 1;
}

int ret=0;
for (int i=maxno;i>0;i--) //当前值从大到小取值,然后将剩余的再递归
{
ret+=dump(number-1,i-1,count-i);
}
return ret;

}

int main(int argc, char*…
[/Quote]

好像没看到哪里有输出这5个数的组合呢?没输出咋看是否正确呢
zhous001 2009-04-29
  • 打赏
  • 举报
回复
我是为分而来!
yinlijun2001 2009-04-29
  • 打赏
  • 举报
回复
int dump(int number,int maxno ,int count)
{
if (number>count || (number==1&&count>maxno))
{
return 0;
}

if (number==1)
{
return 1;
}

int ret=0;
for (int i=maxno;i>0;i--) //当前值从大到小取值,然后将剩余的再递归
{
ret+=dump(number-1,i-1,count-i);
}
return ret;

}

int main(int argc, char* argv[])
{
int rtn=0;
rtn=dump(5,15,42); //5表示5个数 15表示最大的数是15 要达到的值为42
return 0;
}
漁_夫 2009-04-28
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 stormlk1983 的回复:]
是不是要求最多的一组组合?
[/Quote]

所有组合
lpf000 2009-04-28
  • 打赏
  • 举报
回复
然后再判断一下 是否有一样的数字
夹心饼干 2009-04-28
  • 打赏
  • 举报
回复
是不是要求最多的一组组合?
夹心饼干 2009-04-28
  • 打赏
  • 举报
回复
是不是要求最多的一组组合?
liao05050075 2009-04-28
  • 打赏
  • 举报
回复
写得丑点。。来5个for..
#include<stdio.h>
#include<string.h>

int main()
{
int a,b,c,d,e;
for(a=1;a<=11;a++)
for(b=a+1;b<=12;b++)
for(c=b+1;c<=13;c++)
for(d=c+1;d<=14;d++)
for(e=d+1;e<=15;e++)
if(a+b+c+d+e==42) printf("%d %d %d %d %d\n",a,b,c,d,e);
return 0;
}
adfas 2009-04-28
  • 打赏
  • 举报
回复
对这种规模的数据,2楼的程序足够了
koulongfei 2009-04-28
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 pathuang68 的回复:]
5层循环肯定是可以解决问题的。能否用下面的方法降低为4层呢?
1. 1~15中任意4个不同的数字相加得到和sum(这就是4层循环);
2. 令 c = 42-sum,
如果 c < 0, 则不考虑1中的那4个数字的组合;
如果 c > 0, 则看c和1中选取的4个数字是否有重复,如果重复则放弃,而计入1重新计算,如果没有重复,则1中所选取的4个数字和c一共5个数字,就是所求的结果。

这个方法比5层要稍微优化了一点,但基本思路没有突破,属于很不优…
[/Quote]



有思想 期待结果。。。
icesky_ff 2009-04-28
  • 打赏
  • 举报
回复
进来瞧两眼 学习学习
Sou2012 2009-04-28
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 deltamaster 的回复:]
5个for循环次数也太多了。
[/Quote]

up
夹心饼干 2009-04-28
  • 打赏
  • 举报
回复
开了一下午的会,明天再写给你了,这个好写
wzw200 2009-04-28
  • 打赏
  • 举报
回复
没思路
donle1000 2009-04-28
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 donle1000 的回复:]
以前写过一个求M个数中取N个数的组合输出
很类似,改了一下几个数字就行了

[/Quote]

注释如下:


#include <iostream>
using namespace std;

const int m = 15;
const int n = 5;
bool print(int, int, int *, int *);

int main()
{
int *s = new int[m];
for(int i = 0; i < m; i++)
s[i] = i + 1; //初始化1-15
int *rhs = new int[n];
for(int j = 0; j < n; j++)
rhs[j] = s[j]; //提取前5个元素
while(print(m, n, rhs, s));
delete rhs, s;
return 0;
}

bool print(int m, int n, int *rhs, int *res)
{
int flag = 0;
int sum = 0;
for(int i = 0; i < n; i++)
sum += rhs[i]; //计算前5项和是否为42
if(sum == 42)
{
///////////////输出/////////////////
for(int i = 0; i < n; i++)
cout << rhs[i] << '\t';
cout << endl;
}
for(int k = 0; k < n; k++)
if(rhs[k] == res[m - (n - k)])
///////////////////////////////////
//当有第K位元素到他理论上最后的位置
//如:1234,提取3个元素排列,元素2的理论最大位置在初始3的位置
//////////////////////////////////
{
flag = k;
if(k == 0) //如果是最高位,表明所有组合遍历完毕,推出主函数的循环
return 0;
else
for(int y1 = 0; y1 < m; y1++) //否则将理论上第K位向后移一位,后面N-K位同理后移
if(res[y1] == rhs[k - 1])
{
rhs[k - 1] = res[y1 + 1];
break;
}
break;
}
if(flag)
{
int y2;
for(y2 = 0; y2 < m; y2++)
if(res[y2] == rhs[flag - 1])
break;
for(int l = y2 + 1; flag < n; l++, flag++)
rhs[flag] = res[l];
flag = 0;
}
else //没有到理论上的最高位则只需要将最后一个元素移位
{
for(int p = 0; p < m; p++)
if(res[p] == rhs[n - 1])
{
rhs[n - 1] = res[p + 1];
break;
}
}
return 1;
}

beyond071 2009-04-28
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 yinlijun2001 的回复:]
int dump(int number,int maxno ,int count)
{
if (number>count || (number==1&&count>maxno))
{
return 0;
}

if (number==1)
{
return 1;
}

int ret=0;
for (int i=maxno;i>0;i--)
{
ret+=dump(number-1,i-1,count-i);
}
return ret;

}

int main(int argc, char* argv[])
{
int rtn=0;
rtn=dump(5,15,42);
return 0;
}
[/Quote]

没看懂究竟是如何工作的,和本题有啥关系呢
pathuang68 2009-04-28
  • 打赏
  • 举报
回复
5层循环肯定是可以解决问题的。能否用下面的方法降低为4层呢?
1. 1~15中任意4个不同的数字相加得到和sum(这就是4层循环);
2. 令 c = 42-sum,
如果 c < 0, 则不考虑1中的那4个数字的组合;
如果 c > 0, 则看c和1中选取的4个数字是否有重复,如果重复则放弃,而计入1重新计算,如果没有重复,则1中所选取的4个数字和c一共5个数字,就是所求的结果。

这个方法比5层要稍微优化了一点,但基本思路没有突破,属于很不优雅的那种。

思考,42是一个偶数,根据哥德巴赫猜想,任意一个偶数可以由两个素数(prime)相加得到,如19 + 23 = 42,是不是这个题目要从这方面来考虑呢?
beyond071 2009-04-28
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 nuoshueihe 的回复:]

#include <stdio.h>
void main()
{
for (int i=1;i <=15;i++)
{
for (int j=1;j <=15;j++)
{
for (int k=1;k <=15;k++)
{
for (int m=1;m <=15;m++)
{
for (int n=1;n <=15;n++)
{
if (i+j+k+m+n==42&&i!=j&&j!=k&&k!=m&&m!=n&&n!=i)
{
printf("i=%d\tj=%d\tk=%d\tm=%d\tn=%d\n",i,j,k,m,n);
}
}
}
}
}
}
}
[/Quote]
只用5个for的循环输出,无法避免数字顺序不同,但却为同一组的情况。
例如:15 11 6 8 2 和 15 11 6 2 8 实为同一种情况
加载更多回复(5)

65,210

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧