鱼C论坛

 找回密码
 立即注册
查看: 1958|回复: 1

[已解决]C语言解N元方程组

[复制链接]
发表于 2019-4-13 16:21:35 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
给定n×n的矩阵 A=aij,和n×1的列向量B=bi,求列向量X=xi, 使得AX=B
保证方程有唯一解

输入描述

第一行一个数n,表示方程的个数和未知数的个数。

接下来n行,每行n+1个数(可能为小数)。前n个为x1...xn的参数,最后一个为bi

输出描述(保证有唯一解)

n行,每行一个数,表示xi

样例输入

3
1 2 3 4
1 3 4 5
1 2 4 233

样例输出

-227.000000
-228.000000
229.000000


最佳答案
2019-4-13 21:24:22
本帖最后由 Croper 于 2019-4-13 21:32 编辑

线代都忘光了。。

先拿初中的解法写一个吧。。一会复习线代去。。。
#include <stdio.h>

#ifndef _out_
#define _out_
#endif

int FormulaSolve(double** M,int N,double* _out_ ret){
        //当方程只有一个未知数,即方程的形式为ax=b时 
        //printMatrix(M,N);
        
        if (N==1){  
                double* f=M[0];            
                if (f[0]==0. && f[1]!=0.){            //ax=b的方程,当a==0,b!=0时,方程无解 
                        return -1;
                }
                
                ret[0]=0.;                              
                if (f[0]!=0.) ret[0]=f[1]/f[0];     //ax=b的根为x=b/a;
                return 1;
        }
        
        //当方程的未知数数目大于1时,消元
        //寻找一个未知数[0]的系数不为0的方程,用其他方程减去t倍的第一个方程,以消去其他方程的未知数[0] 
        
        //第一步,寻找一个未知数[0]的系数不为0的方程,并把其他方程存入矩阵M2中; 
        int i,j;
        double* f=NULL;
        double *M2[N];  //这里大小为N是为了在方程无解时避免跳出溢出错误,方程一定有解时大小可设为N-1
        j=0;
        for (i=0;i<N;++i){
                if (f==NULL && M[i][0]!=0.){
                        f=M[i];
                        continue;
                }
                M2[j++]=M[i];
        }
        if (f==NULL) return -1;

        //第二部,消去M2中的方程的未知数[0] 
        for (i=0;i<N-1;++i){
                double* fn=M2[i];
                double t=fn[0]/f[0];

                for (j=1;j<N+1;++j){
                        fn[j]-=t*f[j];
                }
                M2[i]++;                      //去除第一个未知数的项 
        }

        //第三步:计算M2的结果 
        int hr= FormulaSolve(M2,N-1,ret+1);
        if (hr==-1) return -1;
        
        //第四步:通过M2的结果反推出未知数[0]的值 
        for (i=1;i<N;++i){
                f[N]-=f[i]*ret[i];
        };
        ret[0]=f[N]/f[0];
        return 1;
}


int main(){
        int N;
        scanf("%d",&N);
        double *M[N];
        int i,j;
        for (i=0;i<N;++i){
                M[i]=(double*)malloc(sizeof(double)*(N+1));
                for (j=0;j<N+1;++j){
                        scanf("%lf",&(M[i][j]));
                }
        }
        
        double ret[N];
        int hr=FormulaSolve(M,N,ret);
        if (hr==-1){
                printf("方程无解"); 
        }
        else{
                for (i=0;i<N;++i){
                        printf("%lf ",ret[i]);
                }
        }        
} 
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-4-13 21:24:22 | 显示全部楼层    本楼为最佳答案   
本帖最后由 Croper 于 2019-4-13 21:32 编辑

线代都忘光了。。

先拿初中的解法写一个吧。。一会复习线代去。。。
#include <stdio.h>

#ifndef _out_
#define _out_
#endif

int FormulaSolve(double** M,int N,double* _out_ ret){
        //当方程只有一个未知数,即方程的形式为ax=b时 
        //printMatrix(M,N);
        
        if (N==1){  
                double* f=M[0];            
                if (f[0]==0. && f[1]!=0.){            //ax=b的方程,当a==0,b!=0时,方程无解 
                        return -1;
                }
                
                ret[0]=0.;                              
                if (f[0]!=0.) ret[0]=f[1]/f[0];     //ax=b的根为x=b/a;
                return 1;
        }
        
        //当方程的未知数数目大于1时,消元
        //寻找一个未知数[0]的系数不为0的方程,用其他方程减去t倍的第一个方程,以消去其他方程的未知数[0] 
        
        //第一步,寻找一个未知数[0]的系数不为0的方程,并把其他方程存入矩阵M2中; 
        int i,j;
        double* f=NULL;
        double *M2[N];  //这里大小为N是为了在方程无解时避免跳出溢出错误,方程一定有解时大小可设为N-1
        j=0;
        for (i=0;i<N;++i){
                if (f==NULL && M[i][0]!=0.){
                        f=M[i];
                        continue;
                }
                M2[j++]=M[i];
        }
        if (f==NULL) return -1;

        //第二部,消去M2中的方程的未知数[0] 
        for (i=0;i<N-1;++i){
                double* fn=M2[i];
                double t=fn[0]/f[0];

                for (j=1;j<N+1;++j){
                        fn[j]-=t*f[j];
                }
                M2[i]++;                      //去除第一个未知数的项 
        }

        //第三步:计算M2的结果 
        int hr= FormulaSolve(M2,N-1,ret+1);
        if (hr==-1) return -1;
        
        //第四步:通过M2的结果反推出未知数[0]的值 
        for (i=1;i<N;++i){
                f[N]-=f[i]*ret[i];
        };
        ret[0]=f[N]/f[0];
        return 1;
}


int main(){
        int N;
        scanf("%d",&N);
        double *M[N];
        int i,j;
        for (i=0;i<N;++i){
                M[i]=(double*)malloc(sizeof(double)*(N+1));
                for (j=0;j<N+1;++j){
                        scanf("%lf",&(M[i][j]));
                }
        }
        
        double ret[N];
        int hr=FormulaSolve(M,N,ret);
        if (hr==-1){
                printf("方程无解"); 
        }
        else{
                for (i=0;i<N;++i){
                        printf("%lf ",ret[i]);
                }
        }        
} 
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-3 14:26

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表