1 组合数
小白书53页上写的组合数中间会乘法溢出,作者举个反例告诉我们:即使你认为题目在“暗示”你使用某种语言特性,也应该深入分析,不能贸然行事。
正确的组合数写法,
#include<stdio.h>
#include<iostream>
using namespace std;
int a[12];
int m,n;
void dfs(int m,int n)
{
for(int i=m;i>=n;i--)
{
a[n]=i;
if(n>1)
{
dfs(i-1,n-1);
}
else
{
for(int j=a[0];j>0;j--)
printf("%d\n",a[j]);
printf("\n");
}
}
}
int main()
{
while(~scanf("%d%d",&m,&n))
{
a[0]=n;
dfs(m,n);
}
return 0;
}
2 全排列,生成1~n的排列 递归实现 (小白书 116页)
void print_permutation(int n,int *A,int cur)
{
int i,j;
if(cur==n) //递归边界
{
for(int i=0;i<n;i++)//尝试在A[cur]中填各种整数 i
{
printf("%d ",A[i]);
}
printf("\n");
}
else
{
for(i=1;i<=n;i++)
{
int ok=1;
for(j=0;j<cur;j++)
{
if(A[j]==i)
ok=0;//如果i已经在A[0]~A[cur-1]中出现过,则不能选
}
if(ok)
{
A[cur]=i;
}
print_permutation(n,A,cur+1);//递归调用
}
}
}
在网上看的另一个代码
#include <stdio.h>
int n = 0;
void swap(int *a, int *b)
{
int m;
m = *a;
*a = *b;
*b = m;
}
void perm(int list[], int k, int m)
{
int i;
if(k > m)
{
for(i = 0; i <= m; i++)
printf("%d ", list[i]);
printf("\n");
n++;
}
else
{
for(i = k; i <= m; i++)
{
swap(&list[k], &list[i]);
perm(list, k + 1, m);
swap(&list[k], &list[i]);
}
}
}
int main()
{
int list[] = {1, 2, 3, 4, 5};
perm(list, 0, 4);
printf("total:%d\n", n);
return 0;
}