在1到100个数中,找出所有10个不同的数的任意组合

yigouxinyue007 2008-03-19 07:40:59
在1到100个数中,找出所有10个不同的数的任意组合

如何快速的求解?
...全文
391 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
oakfire 2008-03-20
  • 打赏
  • 举报
回复
有现成的公式便优先考虑实现公式,别装牛角尖了
laolaoliu2002 2008-03-20
  • 打赏
  • 举报
回复
先排序(目的:删除重复的),然后直接计算就可以了,公式都是现成的.
lyle3 2008-03-20
  • 打赏
  • 举报
回复
ls厉害~
medie2005 2008-03-20
  • 打赏
  • 举报
回复
下面这个lz可以参考一下
#include   <windows.h>
#include <iostream>
#include <iterator>

using namespace std;

void combination( int n, int m ){
int *c=new int[m+2], j;
for( j=1; j<=m; ++j ) c[j]=j-1;
c[m+1]=n;
R2: ;//copy( c+1, c+m+1, ostream_iterator<int>(cout," ") ),cout<<endl;
if( m&1 )
if( c[1]+1<c[2] ){
++c[1]; goto R2;
}
else{
j=2; goto R4;
}
else
if( c[1]>0 ){
--c[1]; goto R2;
}
else{
j=2; goto R5;
};
R4: if( c[j]>=j ){
c[j]=c[j-1]; c[j-1]=j-2; goto R2;
}
else
++j;
R5: if( c[j]+1<c[j+1] ){
c[j-1]=c[j]; c[j]=c[j]+1; goto R2;
}
else{
++j;
if( j<=m ) goto R4;
}
delete []c;
}

int main(int argc, char *argv[])
{
int time=GetTickCount();
combination( 50, 10 );
cout<<GetTickCount()-time<<" ms\n";
return 0;
}
mathe 2008-03-20
  • 打赏
  • 举报
回复
上面代码(50个数选10个)如果不输出,在我的Linux上需要运行28秒,所以如果改成运行100个数选10个,估计需要运行13小时。
如果要输出所有组合,那就麻烦了,储存空间是个大问题
mathe 2008-03-20
  • 打赏
  • 举报
回复
上面代码有错,修改一下

#include <stdio.h>
#define N 50
#define M 10

long long count;
void output(int index[])
{
#ifdef OUTPUT_DATA
int i;
for(i=0;i<M-1;i++){
printf("%d,",index[i]);
}
printf("%d\n",index[i]);
#endif
count++;
}

int main()
{
int index[M];
int i,j;
for(i=1;i<M;i++)index[i]=i+1;
do{
for(j=1;j<index[1];j++){
index[0]=j;
output(index);
}
for(j=1;j<M-1;j++){
if(index[j+1]-index[j]>1)break;
}
index[j]++;
for(i=1;i<j;i++)index[i]=i+1;
}while(j<M-1||index[M-1]<=N);
printf("Total %lld\n",count);
return 0;
}

mathe 2008-03-20
  • 打赏
  • 举报
回复
下面这个版本速度应该还可以。但是总数量太多,还是要花很长时间的。

int index[10];
int i,j;
for(i=1;i<10;i++)index[i]=i+1;
do{
for(j=1;j<index[1];j++){
index[0]=j;
output(index);
}
for(j=1;j<9;j++){
if(index[j+1]-index[j]>1)break;
index[j]++;
}
if(j==9){
index[9]++;
if(index[9]>100)break;
}
}while(1);
sdyqingdao 2008-03-20
  • 打赏
  • 举报
回复
贪婪算法
Dogfish 2008-03-20
  • 打赏
  • 举报
回复
会很慢的。
C(100,10)=100!/(10!*90!)=17,310,309,456,440
yigouxinyue007 2008-03-19
  • 打赏
  • 举报
回复
大牛
野男孩 2008-03-19
  • 打赏
  • 举报
回复
总共有100*99*98*97*96*95*94*94*92*91/(1*2*3*4*5*6*7*8*9*10)这么多个!!

用递归的思想是最直接的,从小到大的顺序,100个数中选10个,先选中1,然后在剩下的99个数中选9个。99选9的方法就跟刚才100选10的方法一样,先选最小的,最小的是2了,然后再从98个中选8个。最后是90个选1个。然后回溯!



#include <stdio.h>

#define MAX_N 100

int g_arr[MAX_N] = {0};
__int64 g_cnt = 0;

void Recur(int* arr, int arr_size, int req_cnt)
{
if (req_cnt > 0)
{
//数据没有选够,从剩下的数据中继续选

//先选中最小的
arr[0] = 1;
//然后从剩下的arr_size - 1个数据中选req_cnt-1个数据
Recur(arr+1, arr_size - 1, req_cnt-1);

//回溯一下,跳过刚才选的那个最小数的情况
arr[0] = 0;
if ((arr_size - 1) >= (req_cnt ))
{
Recur(arr+1, arr_size - 1, req_cnt);
}
}
else
{
//找到一组完整数据
++g_cnt;

//输出组合
for(int i=0; i<MAX_N; i++)
{
if (g_arr[i] == 1)
{
printf("%d\t", i);
}
}
printf("\n");
}
}

int main(int argc, char* argv[])
{
Recur(g_arr, MAX_N, 5);

printf("total group = %I64u\n", g_cnt);
return 0;
}



100选10,规模太大,100选5时,total group = 75287520
fosjos 2008-03-19
  • 打赏
  • 举报
回复
搜一段排列组合的代码,然后把100和10代入
shark003 2008-03-19
  • 打赏
  • 举报
回复
遍历

64,645

社区成员

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

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