哈哈,我做啦,是在电脑报中的“编程点将台”的题目。下面请看我的方法啦!!!!!
方法说明:
主要是运用函数递归的思想来解决的.(最要是-1的递归和+1的递归,详细请看源代码)
1.为了算法的效率有必要除去一些不符合情况.
因为Sum一定在-Len*(Len-1)到Len*(Len-1)之间的.因Sum最大只能是0+1+2+3+4+......(Len-1),也就是Len*(Len-1)/2
2.为了方便查看答案,本程序可以采用逐屏显示的方式,通过按回车查看下一屏(最多20个).
具体操作请看程序的提示.
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
int Sum,Len,All,N,M,K;
double Max;
void run(int,int,int f[]);
void display(int,int);
void main()
{
for(;;)
{
int *p;
K=0;
N=0;
M=0;
All=0;
printf("***请输入Len? Len=");
scanf("%d",&Len);
printf("***请输入Sun? Sum=");
scanf("%d",&Sum);
p=(int *)calloc(Len,sizeof(int));/*动态申请内存来放答案,这样就可以打好长的数啦!!*/
Max=pow(2,Len-1);/*Max是最大可能有的种数,2的Len-1次方*/
getchar();
printf("1.不要逐屏显示请按回车\n");
printf("2.要逐屏显示(每次显示最多20个)输入y再回车");
if(getchar()=='y')/*控制逐屏显示,因为有时候太多情况时,不好查看*/
{
K=1;
getchar();
}
if(Sum<-Len*(Len-1)/2||Sum>Len*(Len-1)/2); /*为了算法的效率,Sum应在-Len*(Len-1)/2到Len*(Len-1)/2之间*/
else
run(0,Len-1,p);
if(N==0)
printf("\n***没有这样的情况!\n");
else
printf("\n总共有 %d 种情况\n\n",All);
free(p);
}
}
void run(int a,int b,int f[])
{
f[b]=a;
if(M<=Max)/*数M控制进行递归调用的次数,最大到达Max*/
if(b>=1) /*控制递归的返回当b=0时*/
{
run(a-1,b-1,f); /*进行-1的递归*/
run(a+1,b-1,f); /*进行+1的递归*/
}
else
{
M++; /*计算递归的次数*/
int add=0;
for(int i=Len-1;i>=0;i--) /*求和add*/
add=add+f[i];
if(add==Sum) /*判断是否符合要求*/
{
printf("\n");
for(int j=Len-1;j>=0;j--)
printf("%d ",f[j]);
N=1; /*标记有符合情况*/
All++; /*统计符合题目要求的情况数All*/
printf(" 情况:%d",All);
display(All,K);
}
}
}
void display(int i,int j)/*控制逐屏显示*/
{
if(i%20==0&&j==1)
for(;;)
{
printf("\n1.要显示下一屏(20个)请按回车\n");
printf("2.取消逐屏显示请输入y再回车");
if(getchar()=='y')
{
K=0;
break;
}
break;
}
}
[此贴子已经被作者于2005-4-13 20:26:20编辑过]