zoukankan      html  css  js  c++  java
  • 题解 P3389 【【模板】高斯消元法】

    题解 P3389 【【模板】高斯消元法】

    看到大家都没有重载运算符,那我就重载一下运算符给大家娱乐一下

    我使用的是高斯-约旦消元法,这种方法是精度最高的(相对地)

    一句话解释高斯约旦消元法:

    通过加减消元法,依次制定x0,并通过加减消元法消去其他方程的x0的系数。对于这样的系数矩阵我们只进行初等变幻保证了其正确性

    看代码吧,主要是希望帮助大家可以学到一些重载的方法

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    inline int qr(void){
    	char c=getchar();
    	int x=0,q=1;
    	while(c<48||c>57)
    		q=c==45?-1:q,c=getchar();
    	while(c>=48&&c<=57)
    		x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return q*x;
    }
    #define RP(t,a,b)	for(int t=(a),edd=(b);t<=edd;t++)
    typedef double db;
    const double EPS=1e-20;//这是坑点,一点要小一点,这个EPS。 
    int n;
    const int maxn=105;
    int ans[maxn];
    inline db fabs(double x){
    	return x>=0?x:-x;
    }
    struct node{
    	db dat[maxn];
    	double& operator [](const int &x){
    		return dat[x];//重载运算符,返回引用 , 就算有dat有更多维,这样就好了,原理有关c++的“地址”系统 
    	}
    	node operator *(const db &x){
    		node ans=(*this);//this是个指针,指向运算符左边的地址 
    		for(int t=1;t<=n+1;t++)
    			ans[t]*=x;
    		return ans;
    	}
    	node operator /(const db &x){
    		node ans=(*this);
    		for(int t=1;t<=n+1;t++)
    			ans[t]/=x;
    		return ans;	
    	}
    	node operator -(node &x){
    		node ans=(*this);
    		for(int t=1;t<=n+1;t++)
    			ans[t]-=x[t];
    		return ans;
    	}
    	node operator *=(const db &x){
    		return (*this)=(*this)*x;
    	}
    	node operator /=(const db &x){
    		return (*this)=(*this)/x;
    	}
    	node operator -=( node &x){
    		return (*this)=(*this)-x;
    	}
    }data[maxn];
    bool vis[maxn];
    inline int big(int x){
    	db ans=0;
    	int ret;
    	for(int t=1;t<=n;t++)
    		if(!vis[t]&&ans<fabs(data[t][x]))
    			ret=t;
    	vis[ret]=1;//根据数学原理,不可重复选择一个方程来消元 
    	return ret;//为了避免乘一个过小的数字,选择一个对于该未知数绝对值最大的系数 
    }
    inline void kkk(void){
    	RP(t0,1,n){
    		int sttd=big(t0);
    		const db a=data[sttd][t0];
    		RP(t,1,n)
    			if(t!=sttd){
    				if(fabs(data[t][t0])<EPS){
    					cout<<"No Solution";//防止除0 
    					return;
    				}
    				data[t]*=(a/data[t][t0]),data[t]-=data[sttd];//将选定x0的系数和基准方程变为一致,在通过加减消元消掉,
    															 //此后该未知数的系数就是0,不会再产生影响 
    			}
    		ans[t0]=sttd;//记录结果是哪个方程得出的 
    	}
    	RP(t,1,n)
    		if(fabs(data[ans[t]][t])<EPS){
    			cout<<"No Solution"<<endl;
    			return;
    		}
    	RP(t,1,n){
    		printf("%.2lf
    ",(data[ans[t]][n+1]/data[ans[t]][t]));
    	}
    	return;
    }
    int main(){
    	n=qr();
    	RP(t,1,n)
    		RP(i,1,n+1)
    			data[t][i]=qr();
    	kkk();
    	return 0;//功德圆满 
    }
    
    
  • 相关阅读:
    Python基础-----lambda匿名函数
    Python基础-----函数嵌套及作用域
    Python基础-----递归
    Python基础-----函数
    Python基础-----字符串格式化
    Python基础-----数据类型
    Python基础-----运算符
    Python基础-----while循环练习
    Python基础-----while循环语句
    Python基础-----条件语句与初识基本数据类型(二)
  • 原文地址:https://www.cnblogs.com/winlere/p/10308125.html
Copyright © 2011-2022 走看看