发个自己的解,对于n比较小的方程应该没问题,大的的话不敢说,从文件input.txt输入
具体思路是用二分求解,但是为了保证求到所有的解就必须要选好分割点,其实分割点可以选每个极大点和极小点及无穷远点,求极点的问题转化到求f'(x)=0
#include <stdio.h>
#include <math.h>
#define Rmax 11
#define K 0.0001
double eq[Rmax][Rmax];
double so[Rmax][Rmax];
int snum[Rmax];
double f(double b[],int rmax,double x)
{
double ans=b[rmax];
while(rmax--)
ans=ans*x+b[rmax];
return ans;
}
double getx(double b[],int rmax,double l,double r)
{
char sl,sr,sm;
double m;
sl=f(b,rmax,l)>0;sr=f(b,rmax,r)>0;
m=(l+r)/2;sm=f(b,rmax,m)>0;
while((l+K)<=r){
if(sl^sm){ r=m;sr=sm; }
else { l=m;sl=sm; }
m=(l+r)/2;sm=f(b,rmax,m)>0;
}
if(sm) return m;
else
if(sr) return r;
else return l;
}
double findmax(double b[],int rmax,double st,double p)
{
char smax=((p>0)||!(rmax&1))^(b[rmax]<0);
while((f(b,rmax,st+p)>0)^smax)
p*=2;
return (st+p);
}
FILE *fi,*fo;
void init(int n)
{
int i,j;
for(i=n;i>=0;i--)
fscanf(fi,"%lf",&eq[n][i]);
for(i=n-1;i>=1;i--)
for(j=i+1;j>=1;j--)
eq[i][j-1]=eq[i+1][j]*j;
}
void printans(double b[],int rmax,double s[],int num)
{
int i,t=rmax;
fprintf(fo,"The answer of equation:");
fprintf(fo,"%.2lfx^%d",b[rmax],rmax);
while(--rmax)
if(b[rmax]>0) fprintf(fo,"+%.2lfx^%d",b[rmax],rmax);
else if(b[rmax]<0) fprintf(fo,"%.2lfx^%d",b[rmax],rmax);
if(b[0]>0) fprintf(fo,"+%.2lf",b[0]);
else if(b[0]<0) fprintf(fo,"%.2lf",b[0]);
fprintf(fo,"=0\n");
if(num)
for(i=0;i<num;i++)
fprintf(fo,"%.2lf %.2f\n",s[i],f(b,t,s[i]));
else fprintf(fo,"No solution\n");
fprintf(fo,"\n");
}
void addx(double s[],int *num,double x)
{
if((*num)&&fabs(x-s[(*num)-1])<K) return;
s[(*num)++]=x;
}
#define Ok(a,b) (f(eq[i],i,a)>0)^(f(eq[i],i,b)>0)
void work(int n)
{
int i,j,num,t;
double x1,x2;
snum[1]=1;so[1][0]=-(eq[1][0]/eq[1][1]);
for(i=2;i<=n;i++){
num=snum[i-1];
if(!num){
x1=findmax(eq[i],i,0,-1);
x2=findmax(eq[i],i,0,1);
if(i&1){ so[i][0]=getx(eq[i],i,x1,x2); snum[i]=1;}
else snum[i]=0;
}
else{
snum[i]=0;
x1=findmax(eq[i],i,so[i-1][0],-1);
x2=findmax(eq[i],i,so[i-1][num-1],1);
if(Ok(x1,so[i-1][0]))
addx(so[i],&snum[i],getx(eq[i],i,x1,so[i-1][0]));
for(j=1;j<num;j++)
if(Ok(so[i-1][j-1],so[i-1][j])) {
addx(so[i],&snum[i],getx(eq[i],i,so[i-1][j-1],so[i-1][j]));
}
if(Ok(x2,so[i-1][num-1]))
addx(so[i],&snum[i],getx(eq[i],i,so[i-1][num-1],x2));
}
}
printans(eq[n],n,so[n],snum[n]);
}
int main(void)
{
int n;
fi=fopen("input.txt","r");
fo=stdout;
while(fscanf(fi,"%d",&n)==1){
init(n);work(n);
}
fclose(fi);getch();
return 0;
}
具体思路是用二分求解,但是为了保证求到所有的解就必须要选好分割点,其实分割点可以选每个极大点和极小点及无穷远点,求极点的问题转化到求f'(x)=0
#include <stdio.h>
#include <math.h>
#define Rmax 11
#define K 0.0001
double eq[Rmax][Rmax];
double so[Rmax][Rmax];
int snum[Rmax];
double f(double b[],int rmax,double x)
{
double ans=b[rmax];
while(rmax--)
ans=ans*x+b[rmax];
return ans;
}
double getx(double b[],int rmax,double l,double r)
{
char sl,sr,sm;
double m;
sl=f(b,rmax,l)>0;sr=f(b,rmax,r)>0;
m=(l+r)/2;sm=f(b,rmax,m)>0;
while((l+K)<=r){
if(sl^sm){ r=m;sr=sm; }
else { l=m;sl=sm; }
m=(l+r)/2;sm=f(b,rmax,m)>0;
}
if(sm) return m;
else
if(sr) return r;
else return l;
}
double findmax(double b[],int rmax,double st,double p)
{
char smax=((p>0)||!(rmax&1))^(b[rmax]<0);
while((f(b,rmax,st+p)>0)^smax)
p*=2;
return (st+p);
}
FILE *fi,*fo;
void init(int n)
{
int i,j;
for(i=n;i>=0;i--)
fscanf(fi,"%lf",&eq[n][i]);
for(i=n-1;i>=1;i--)
for(j=i+1;j>=1;j--)
eq[i][j-1]=eq[i+1][j]*j;
}
void printans(double b[],int rmax,double s[],int num)
{
int i,t=rmax;
fprintf(fo,"The answer of equation:");
fprintf(fo,"%.2lfx^%d",b[rmax],rmax);
while(--rmax)
if(b[rmax]>0) fprintf(fo,"+%.2lfx^%d",b[rmax],rmax);
else if(b[rmax]<0) fprintf(fo,"%.2lfx^%d",b[rmax],rmax);
if(b[0]>0) fprintf(fo,"+%.2lf",b[0]);
else if(b[0]<0) fprintf(fo,"%.2lf",b[0]);
fprintf(fo,"=0\n");
if(num)
for(i=0;i<num;i++)
fprintf(fo,"%.2lf %.2f\n",s[i],f(b,t,s[i]));
else fprintf(fo,"No solution\n");
fprintf(fo,"\n");
}
void addx(double s[],int *num,double x)
{
if((*num)&&fabs(x-s[(*num)-1])<K) return;
s[(*num)++]=x;
}
#define Ok(a,b) (f(eq[i],i,a)>0)^(f(eq[i],i,b)>0)
void work(int n)
{
int i,j,num,t;
double x1,x2;
snum[1]=1;so[1][0]=-(eq[1][0]/eq[1][1]);
for(i=2;i<=n;i++){
num=snum[i-1];
if(!num){
x1=findmax(eq[i],i,0,-1);
x2=findmax(eq[i],i,0,1);
if(i&1){ so[i][0]=getx(eq[i],i,x1,x2); snum[i]=1;}
else snum[i]=0;
}
else{
snum[i]=0;
x1=findmax(eq[i],i,so[i-1][0],-1);
x2=findmax(eq[i],i,so[i-1][num-1],1);
if(Ok(x1,so[i-1][0]))
addx(so[i],&snum[i],getx(eq[i],i,x1,so[i-1][0]));
for(j=1;j<num;j++)
if(Ok(so[i-1][j-1],so[i-1][j])) {
addx(so[i],&snum[i],getx(eq[i],i,so[i-1][j-1],so[i-1][j]));
}
if(Ok(x2,so[i-1][num-1]))
addx(so[i],&snum[i],getx(eq[i],i,so[i-1][num-1],x2));
}
}
printans(eq[n],n,so[n],snum[n]);
}
int main(void)
{
int n;
fi=fopen("input.txt","r");
fo=stdout;
while(fscanf(fi,"%d",&n)==1){
init(n);work(n);
}
fclose(fi);getch();
return 0;
}
我喜欢创造,一只扑腾着翅膀向天空飞翔的乌鸦