a1 + a2 + a3 + … + an = s
1 / a1 + 1 / a2 + 1 / a3 + … + 1 / an = 1
其中n, a1, a2 …均为参数,s已知。
给出s求出不定方程组的一组正整数解。
小弟有礼了~~~~
#include <stdio.h> #include <conio.h> #include <math.h> #include <stdlib.h>
#define TRUE 1 #define FALSE 0
#define BASEROOT 1 #define EPSILON 1e-24
typedef unsigned char BOOL;
static int rootcount;
/* 求两数中较大的数 */ double max(double,double); /* 比较两个浮点数是否相等 */ BOOL approx_equal(double,double); /* 计算整数解是否满足1/a1+1/a2+1/a3+...+1/an=1 */ BOOL judge(int *,int); /* 初始化数组 */ void init(int *,int); /* 利用回朔穷举所有可能整数解 */ void solve(int *,int,int);
int main() { int *roots,s; /* 初始化全局变量,假设最初误解*/ rootcount=0; printf("Please input the value of s="); scanf("%d",&s); if(s<=0) {printf("Input error!\n"); return 0;} /* 考虑根最多的情况时为指针分配适当的空间 */ roots=(int*)malloc((s/BASEROOT)*sizeof(int)); if(!roots) {printf("Cannot allocate memory!\n"); return 0;} /* 初始化数组 */ init(roots,s/BASEROOT); /* 求解并打印结果 */ solve(roots,s,0); /* 释放内存 */ free(roots); if(!rootcount) printf("No root at all!\n"); getch(); return 1; }
double max(double a,double b) { return a>b?a:b; }
BOOL approx_equal(double a,double b) { if(!a&&b) return fabs(b)<=EPSILON; if(a&&!b) return fabs(a)<=EPSILON; return (fabs(a-b)/max(fabs(a),fabs(b)))<=EPSILON; }
BOOL judge(int *roots,int pos) { register int i; double result; for(result=0,i=0;roots[i]&&i<=pos;result+=(1.0)/roots[i++]); if(approx_equal(result,1.0)) return TRUE; else return FALSE; }
void init(int *roots,int size) { register int i; for(i=0;i<size;roots[i++]=0); }
void solve(int *roots,int sum,int pos) { register int i; /* 当和数仍然不为0时,执行以下过程 */ if(sum) { if(sum==1) { /* 当和数为1时,最后可取的数字也只有1 */ roots[pos]=1; solve(roots,0,pos); } else { /* 当和数大于1时,可取得数字范围从1~(sum-1)使得最小的情况1,和最大 的情况sum-1他们的和仍然为sum,保证了若干根相加后仍等于sum */ for(i=BASEROOT;i<sum;i++) { roots[pos++]=i; /* 执行递归 */ solve(roots,sum-i,pos); pos--; } } } else { /* 判断所求的若干的根是否满足1/a1+1/a2+...+1/an=1 */ if(judge(roots,pos)) { rootcount++; i=0; while(roots[i]&&i<=pos) printf("roots[%d]=%4d",i,roots[i++]); printf("\n"); } } } 大家来帮忙看看,我这个方法是不是正确,为什么我取了n组数据测试,都没有解。。
[此贴子已经被作者于2005-4-26 18:01:59编辑过]
#include <stdio.h> #include <conio.h> #include <math.h> #include <stdlib.h>
#define TRUE 1 #define FALSE 0
#define BASEROOT 1 #define EPSILON 1e-24
typedef unsigned char BOOL;
static int rootcount;
/* 求两数中较大的数 */ double max(double,double); /* 比较两个浮点数是否相等 */ BOOL approx_equal(double,double); /* 计算整数解是否满足1/a1+1/a2+1/a3+...+1/an=1 */ BOOL judge(int *,int); /* 初始化数组 */ void init(int *,int); /* 利用回朔穷举所有可能整数解 */ void solve(int *,int,int);
int main() { int *roots,s; /* 初始化全局变量,假设最初误解*/ rootcount=0; printf("Please input the value of s="); scanf("%d",&s); if(s<=0) {printf("Input error!\n"); return 0;} /* 考虑根最多的情况时为指针分配适当的空间 */ roots=(int*)malloc((s/BASEROOT)*sizeof(int)); if(!roots) {printf("Cannot allocate memory!\n"); return 0;} /* 初始化数组 */ init(roots,s/BASEROOT); /* 求解并打印结果 */ solve(roots,s,0); /* 释放内存 */ free(roots); if(!rootcount) printf("No root at all!\n"); getch(); return 1; }
double max(double a,double b) { return a>b?a:b; }
BOOL approx_equal(double a,double b) { if(!a&&b) return fabs(b)<=EPSILON; if(a&&!b) return fabs(a)<=EPSILON; return (fabs(a-b)/max(fabs(a),fabs(b)))<=EPSILON; }
BOOL judge(int *roots,int pos) { register int i; double result; for(result=0,i=0;roots[i]&&i<=pos;result+=(1.0)/roots[i++]); if(approx_equal(result,1.0)) return TRUE; else return FALSE; }
void init(int *roots,int size) { register int i; for(i=0;i<size;roots[i++]=0); }
void solve(int *roots,int sum,int pos) { register int i; /* 当和数仍然不为0时,执行以下过程 */ if(sum) { for(i=BASEROOT;i<=sum;i++) { roots[pos++]=i; /* 执行递归 */ solve(roots,sum-i,pos); roots[pos]=0; pos--; } } else { /* 判断所求的若干的根是否满足1/a1+1/a2+...+1/an=1 */ if(judge(roots,pos)) { rootcount++; i=0; while(roots[i]&&i<=pos) printf("roots[%d]=%2d ",i,roots[i++]); printf("\n"); } } } 我找到问题了,原来我昨天的算法是漏解得,今天贴上修正的算法。。。