昨天的题目搞定

题目:生成6选4的所有组合

把贴过的两个算法:DFS生成排列和字典序生成组合捏合到了一起,没做什么优化,只是统一了一下接口

#include <stdio.h>
#define MAX 100
int num[MAX]={0};
int counter=1;
int visited[20];
int workarr[20];
int elem[20]={0};
FILE *fp;
int count=0;
void DFS(int l,int n)//l为深搜的位,n为元素的个数
{
 int i;
    if (l == n)
    { 
        for (i=0; i<l; i++)
            fprintf(fp,"%d", workarr[i]);
   fprintf(fp," ");
   count++;
   if(count%12==0)
    fprintf(fp,"/n");
        return;
     }
     for (i=0; i<n; i++)
         if (!visited[i])
         {
             visited[i] = 1;//确保不重复
             workarr[l] = elem[i];
             DFS(l+1,n);
             visited[i] = 0;
         }
}
//属于关系
int find(int n,int elem)
{
 int i;
 for(i=1;i<=n;i++)
  if(num[i]==elem)
   return 1;
 return 0;
}

//递归调用生成下一个组合,m,n为C(m,n)中的m,n
//找到这样的n:a[n]+1<=n且a[n]+1不属于num[]
void next(int m,int n,int he)
{
int i,j;
int temp;
copy(n);
DFS(0,n);
fprintf(fp,"/n");
//for(i=1;i<=n;i++)
//printf("%d ",num[i]);
//printf("/n");
if(counter==he) return ;
for(i=n;i>=1;i--)
{
 if(num[i]+1<=m && !find(n,num[i]+1))
 {
  temp=num[i]+1;
  for(j=i;j<=n;j++)
  {
   num[j]=temp++;
  }
  break;
 }
}
counter++;
next(m,n,he);
}

//阶乘m!
int  factor(int n)
{
 if(n==1)
  return 1;
 else
  return n*factor(n-1);
}
//组合C(m,n)
int assemble(int m,int n)
{
 return factor(m)/(factor(n)*factor(m-n));
}

int copy(int n)
{
 int i;
 for(i=0;i<n;i++)
  elem[i]=num[i+1];
}

 

main()
{
//C(m,n)
int m=6,n=4;
//初始化
int i;
if((fp=fopen("output.txt","w"))==NULL)
{
 printf("error in opening file");
 exit(0);
}
for(i=1;i<=n;i++)
num[i]=i;
//调用next(m,n)生成组合
next(m,n,assemble(m,n));
fprintf(fp,"共%d种/n",count);
}

结果文件output.txt内容如下
1234 1243 1324 1342 1423 1432 2134 2143 2314 2341 2413 2431
3124 3142 3214 3241 3412 3421 4123 4132 4213 4231 4312 4321

1235 1253 1325 1352 1523 1532 2135 2153 2315 2351 2513 2531
3125 3152 3215 3251 3512 3521 5123 5132 5213 5231 5312 5321

1236 1263 1326 1362 1623 1632 2136 2163 2316 2361 2613 2631
3126 3162 3216 3261 3612 3621 6123 6132 6213 6231 6312 6321

1245 1254 1425 1452 1524 1542 2145 2154 2415 2451 2514 2541
4125 4152 4215 4251 4512 4521 5124 5142 5214 5241 5412 5421

1246 1264 1426 1462 1624 1642 2146 2164 2416 2461 2614 2641
4126 4162 4216 4261 4612 4621 6124 6142 6214 6241 6412 6421

1256 1265 1526 1562 1625 1652 2156 2165 2516 2561 2615 2651
5126 5162 5216 5261 5612 5621 6125 6152 6215 6251 6512 6521

1345 1354 1435 1453 1534 1543 3145 3154 3415 3451 3514 3541
4135 4153 4315 4351 4513 4531 5134 5143 5314 5341 5413 5431

1346 1364 1436 1463 1634 1643 3146 3164 3416 3461 3614 3641
4136 4163 4316 4361 4613 4631 6134 6143 6314 6341 6413 6431

1356 1365 1536 1563 1635 1653 3156 3165 3516 3561 3615 3651
5136 5163 5316 5361 5613 5631 6135 6153 6315 6351 6513 6531

1456 1465 1546 1564 1645 1654 4156 4165 4516 4561 4615 4651
5146 5164 5416 5461 5614 5641 6145 6154 6415 6451 6514 6541

2345 2354 2435 2453 2534 2543 3245 3254 3425 3452 3524 3542
4235 4253 4325 4352 4523 4532 5234 5243 5324 5342 5423 5432

2346 2364 2436 2463 2634 2643 3246 3264 3426 3462 3624 3642
4236 4263 4326 4362 4623 4632 6234 6243 6324 6342 6423 6432

2356 2365 2536 2563 2635 2653 3256 3265 3526 3562 3625 3652
5236 5263 5326 5362 5623 5632 6235 6253 6325 6352 6523 6532

2456 2465 2546 2564 2645 2654 4256 4265 4526 4562 4625 4652
5246 5264 5426 5462 5624 5642 6245 6254 6425 6452 6524 6542

3456 3465 3546 3564 3645 3654 4356 4365 4536 4563 4635 4653
5346 5364 5436 5463 5634 5643 6345 6354 6435 6453 6534 6543

共360种

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值