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; }