C语言 信封
试编程求出完全装错情形的所有方式及其总量s。例如,输入n=3,即有3封信需要装入信封,完全装错的一种方式可以表示为312,表示第1封信装入第3个信封,第2封信装入第1个信封,第3封信装入第2个信封。对于n=3,完全装错的方式共有2种,分别是312和231.我知道可能需要用两个数组,但是表达不出来,求不用指针的做法!
[ 本帖最后由 傻瓜菜 于 2011-11-13 14:42 编辑 ]
程序代码:#include<stdio.h>
#define NUM 100 /*定义数组的大小*/
int a[NUM+1];
int main()
{
int i,k,flag,not_finish=1,count=0,flag_2;
i=1; /*正在处理的元素下标,表示前i-1个元素已符合要求,正在处理第i个元素*/
a[1]=1; /*为数组的第一个元素赋初值*/
int n;
do
{
printf("输入信封数量:");
scanf("%d",&n);
}while(n<1);
printf("结果如下:\n");
if(n==1)
{
printf("没有错误的可能。\n");
}
else if(n==2)
{
printf(" [ 1]: 2 1\n");
}
else
{
while(not_finish) /*not_finish=1:处理尚未结束*/
{
while(not_finish&&i<=n) /*处理尚未结束且还没处理到第n个元素*/
{
for(flag=1,k=1;flag&&k<i;k++) /*判断是否有多个皇后在同一行*/
{
if(a[k]==a[i])flag=0;
}
// for(k=1;flag&&k<i;k++) /*判断是否有多个皇后在同一对角线*/
// {
// if((a[i]==a[k]-(k-i))||(a[i]==a[k]+(k-i))) flag=0;
// }
if(!flag) /*若存在矛盾不满足要求,需要重新设置第i个元素*/
{
if(a[i]==a[i-1]) /*若a[i]的值已经经过一圈追上a[i-1]的值*/
{
i--; /*退回一步,重新试探处理前一个元素*/
if(i>1&&a[i]==n)
a[i]=1; /*当a[i]为n时将a[i]的值置1*/
else if(i==1&&a[i]==n)
not_finish=0; /*当第一位的值达到n时结束*/
else a[i]++; /*将a[i]的值取下一个值*/
}
else if(a[i]==n) a[i]=1;
else a[i]++; /*将a[i]的值取下一个值*/
}
else if(++i<=n)
{
if(a[i-1]==n) a[i]=1; /*若前一个元素的值为NUM则a[i]=1*/
else a[i]=a[i-1]+1; /*否则元素的值为前一个元素的下一个值*/
}
}
if(not_finish)
{
flag_2=1;
for(int kk=1;kk<=n;kk++)
{
if(a[kk]==kk)
flag_2=0;
}
if(flag_2==1)
{
++count;
printf((count-1)%3?"\n [%2d]: ":"\n [%2d]: ",count);
for(k=1;k<=n;k++) /*输出结果*/
{
printf(" %d",a[k]);
}
}
if(a[n-1]<n) a[n-1]++; /*修改倒数第二位的值*/
else a[n-1]=1;
i=n-1; /*开始寻找下一个足条件的解*/
}
}
}
printf("\n");
return 0;
}
程序代码:/* Note:Your choice is C IDE */
#include "stdio.h"
#include "math.h"
int num[30]={0};
int add(int i,int n)//对数组进行+1处理,达到最大数向前进1,同时当前位置0.
{
num[i]++;
if(i==0&&num[i]>n)
{
printf("数据出错");
return 0;
}
else if (num[i]>=n)//大于n表示要向前进一位
{
num[i]=0;
return add(i-1,n);
}
return 1;
}
int camp(int n)//对各位数进行比较处理
{
int i,ok;
if(num[n]==n)//n位上等于n,信正确反回错
{
return 0;
}
if(n==0)
return 1;
else
{
ok=camp(n-1);
if (!ok)
return 0;
}
for (i=n-1;i>=0;i--)
{
if(num[i]==num[n])//有相同数,反回错
{
return 0;
}
}
return 1;
}
int main()
{
int n=1,n2,i,j,ok,count=0,p;
printf("请输入信封数:");
scanf("%d",&n);
while(n<=1)
{
printf("请输入一个大于1的整数:");
scanf("%d",&n);
}
n2=pow(n,n);
for(i=0;i<n2;i++)
{
add(n-1,n);
// for(p=0;p<n;p++)
// printf("%d",num[p]);
// printf("\n");
ok=camp(n-1);
if(ok)
{
count++;
for(j=0;j<n;j++)
{
printf("%d",num[j]+1);
}
printf(" ");
if(count%10==0)
printf("\n");
}
}
printf("\n最大全错数为:%d\n",count);
return 1;
}