怎样输出一个C(m,n)组合的所有结果? 怎样输出一个C(m,n)组合的所有结果?急啊~不知道该怎样编程把所有的结果输出来,谁能帮帮我? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 void ComeBack(int m,int r){ int i,j; int a[20]; i=0; a[i]=0; int kk=0; do{ if(a[i]-i<=m-r) { if(i==r-1) { for(j=0;j<r;j++) printf("%d",a[j]); printf("\n"); kk++; a[i]++; continue; } i++; a[i]=a[i-1]+1; } else { if(i==0) {printf("kk=%d\n",kk); return; } a[--i]++; } }while(1); } 给你一点资料,就能解决了本程序的思路是开一个数组,其下标表示1到m个数,数组元素的值为1表示其下标代表的数被选中,为0则没选中。 首先初始化,将数组前n个元素置1,表示第一个组合为前n个数。 然后从左到右扫描数组元素值的“10”组合,找到第一个“10”组合后将其变为“01”组合,同时将其左边的所有“1”全部移动到数组的最左端。 当第一个“1”移动到数组的m-n的位置,即n个“1”全部移动到最右端时,就得到了最后一个组合。 例如求5中选3的组合: 1 1 1 0 0 //1,2,3 1 1 0 1 0 //1,2,4 1 0 1 1 0 //1,3,4 0 1 1 1 0 //2,3,4 1 1 0 0 1 //1,2,5 1 0 1 0 1 //1,3,5 0 1 1 0 1 //2,3,5 1 0 0 1 1 //1,4,5 0 1 0 1 1 //2,4,5 0 0 1 1 1 //3,4,5 程序如下: #include "stdio.h" #include "time.h" unsigned char number[100]; //最多求100个数的组合。 unsigned int m,n;// 2<=m<=100,n<m char tmpbuf[128]; time_t ltime; struct tm *today; void printtime(void) //打印当前时间的函数 { time(<ime); today = localtime(<ime ); strftime(tmpbuf,128,"%Y-%m-%d %H:%M:%S",today); printf("%s\n",tmpbuf); } void inition() //初始化 { unsigned int i; for(i=0;i<n;i++) number[i]=1; } void output() //输出组合结果 { unsigned int i; for(i=0;i<m;i++) if(number[i]) printf("%02d ",i+1); printf("\n"); } void main() { unsigned long count; //计数组合个数 unsigned int i,j,k,l; bool findfirst,end,swap; end=false; printf("please input m:"); scanf("%d",&m); //输入m printf("please input n:"); scanf("%d",&n); //输入n printtime(); //打印开始时间 inition(); //初始化 //output(); //屏蔽掉结果输出以节约时间 count=1; j=m; while(!end) { findfirst=false; swap=false; //标志复位 for(i=0;i<j;i++) { if(!findfirst && number[i]) { k=i; //k记录下扫描到的第一个数 findfirst=true; //设置标志 } if(number[i] && !number[i+1]) //从左到右扫描第一个“10”组合 { number[i]=0; number[i+1]=1; swap=true; //设置交换标志 for(l=0;l<i-k;l++) number[l]=number[k+l]; for(l=i-k;l<i;l++) number[l]=0; //交换后将之前的“1”全部移动到最左端 if(k==i && i+1==m-n) //如果第一个“1”已经移动到了m-n的位置,说明这是最后一个组合了。 end=true; } if(swap) //交换一次后就不用继续找“10”组合了 break; } //output(); //屏蔽掉结果输出以节约时间 count++; //组合数计数器递增1 } printtime(); //打印结束时间 printf("total number of combination is: %d\n",count); //打印总的组合数getchar(); } 在vc5.0下编译通过. 在我的p166 16M RAM机器上算30中选10 的组合,屏蔽掉结果输出花了33秒时间。 网络中传输数据时间的估计问题 在视类函数中,执行后 画不出来 咋回事 调用dll时参数的传递问题 WIN 2003下ADO连接ACCESS数据库出问题 ,权限不够,如何解决? 怎样在while语句里响应按键? ICE还是ACE? 急求directCD下载(重分相赠) 请教如何从串口读数据。急,急 ··召唤各位vc大虾,进来留下oicq号,大家交个朋友·· Installshield打包的安装包如何编辑 在WIN32程序中如何用MESSAGEBOX() 关于socket设置问题
{
int i,j;
int a[20];
i=0;
a[i]=0;
int kk=0;
do{
if(a[i]-i<=m-r)
{
if(i==r-1)
{
for(j=0;j<r;j++)
printf("%d",a[j]);
printf("\n");
kk++;
a[i]++;
continue;
}
i++;
a[i]=a[i-1]+1;
}
else
{
if(i==0)
{printf("kk=%d\n",kk);
return;
}
a[--i]++;
}
}while(1);
}
本程序的思路是开一个数组,其下标表示1到m个数,数组元素的值为1表示其下标
代表的数被选中,为0则没选中。
首先初始化,将数组前n个元素置1,表示第一个组合为前n个数。
然后从左到右扫描数组元素值的“10”组合,找到第一个“10”组合后将其变为
“01”组合,同时将其左边的所有“1”全部移动到数组的最左端。
当第一个“1”移动到数组的m-n的位置,即n个“1”全部移动到最右端时,就得
到了最后一个组合。
例如求5中选3的组合:
1 1 1 0 0 //1,2,3
1 1 0 1 0 //1,2,4
1 0 1 1 0 //1,3,4
0 1 1 1 0 //2,3,4
1 1 0 0 1 //1,2,5
1 0 1 0 1 //1,3,5
0 1 1 0 1 //2,3,5
1 0 0 1 1 //1,4,5
0 1 0 1 1 //2,4,5
0 0 1 1 1 //3,4,5 程序如下: #include "stdio.h"
#include "time.h" unsigned char number[100]; //最多求100个数的组合。
unsigned int m,n;// 2<=m<=100,n<m char tmpbuf[128];
time_t ltime;
struct tm *today; void printtime(void) //打印当前时间的函数
{
time(<ime);
today = localtime(<ime );
strftime(tmpbuf,128,"%Y-%m-%d %H:%M:%S",today);
printf("%s\n",tmpbuf);
} void inition() //初始化
{
unsigned int i;
for(i=0;i<n;i++)
number[i]=1;
} void output() //输出组合结果
{
unsigned int i;
for(i=0;i<m;i++)
if(number[i])
printf("%02d ",i+1);
printf("\n");
} void main()
{
unsigned long count; //计数组合个数
unsigned int i,j,k,l;
bool findfirst,end,swap;
end=false;
printf("please input m:");
scanf("%d",&m); //输入m
printf("please input n:");
scanf("%d",&n); //输入n
printtime(); //打印开始时间
inition(); //初始化
//output(); //屏蔽掉结果输出以节约时间
count=1;
j=m;
while(!end)
{
findfirst=false;
swap=false; //标志复位
for(i=0;i<j;i++)
{
if(!findfirst && number[i])
{
k=i; //k记录下扫描到的第一个数
findfirst=true; //设置标志
}
if(number[i] && !number[i+1]) //从左到右扫描第一个“10”组合
{
number[i]=0;
number[i+1]=1;
swap=true; //设置交换标志
for(l=0;l<i-k;l++)
number[l]=number[k+l];
for(l=i-k;l<i;l++)
number[l]=0; //交换后将之前的“1”全部移动到最左端
if(k==i && i+1==m-n) //如果第一个“1”已经移动到了m-n的位置,说明
这是最后一个组合了。
end=true;
}
if(swap) //交换一次后就不用继续找“10”组合了
break;
}
//output(); //屏蔽掉结果输出以节约时间
count++; //组合数计数器递增1
}
printtime(); //打印结束时间
printf("total number of combination is: %d\n",count); //打印总的组合数getchar();
} 在vc5.0下编译通过.
在我的p166 16M RAM机器上算30中选10 的组合,屏蔽掉结果输出花了33秒时间。