伯努利装错信封问题的一般表述为:
某人写了n封信,写了这n封信对应的有n个信封,把所有的信都装错信封的情况共有多少种?
解题思路:
把n封信分别命为1到n,n个信封命为i[1]到i[n],然后由第一个信封开始依次拿信,如果拿到一封符合条件的(即不对应自己编号,也不会与前面信封存在的信的编号重合)即迭代进去下一信封的拿信.
程序实现功能:输入一个数n,输出符合条件的所有情况及情况总数.
#include<stdio.h>
#include<math.h>
int i[30],pol=0;//定义为全局变量
void def(int que,int num)
{
int n,a,b,m,key;
for(n=1;n<=num;n++)//模拟第que个信封依次拿所有序号
{
i[que]=n;//拿入信
key=1;
for(m=1;m<que;m++)//判断是否重复拿取或处于正确的信封
if(i[que]==i[m]||i[que]==que)
{
key=0;
break;
}
if(que==1&&i[que]==1)key=0;//由于上述的判断无法对第一封信进行判断,所以单独判断
if(key==0)continue;//
if(que==num)//当gue=num,信封装满,又符合条件,即一种情况出现,输出
{
pol++;
printf(" ");
for(m=1;m<=num;m++)
printf("%d",i[m]);
if(pol%5==0&&pol!=0)printf("\n");
break;
}
def(que+1,num);// 信封未装满,进入下一信封
}
}
int main()
{
int num;
scanf("%d",&num);
def(1,num);
printf("\nThe total number is %d\n",pol);
return 0;
}