【cdoj 1330】柱爷与远古法阵 高斯消元

47 篇文章 0 订阅
30 篇文章 0 订阅

毕竟是本人的第一次写高斯消元,所以你会发现代码与题解神似,至于为什么,无可奉告

其实思想蛮简单,主要来谈谈代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#define maxn 305
#define esp (1e-14)
using namespace std;
int n,m,f[maxn];
long double a[maxn][maxn];//构造的高斯消元的矩阵,代表第i个方程式的第j个系数是多少 ,精度要求很高 

void read(int& x){
	x=0;
	char c=getchar();
	for(;c<'0'||c>'9';c=getchar());
	for(;c>='0' && c <= '9'; c = getchar()  ){
		x = x*10 + c - '0';
	}
}


int main(){
	read( n );read(m);//读入优化 
	int x,y;
	for(int i=1;i <= m ; i++){
		read(x);read(y);
		f [ x ] = y;//如果有传送的话,到哪里 
	}
	
	for(int i = 1 ; i < n ; i++ ){
		a[ i ][ i ]=6;//第一个方程  
		if( f[ i ] )a[ i ][ f[ i ] ]=-6.0;//如果有传送门 系数直接抵消 x-y=0 相当于 x=y 
		else{
			a[i][n+1]=6.0;//方程右边的常数 
			for(int j = 1 ;j <= 6; j++){
				if(i+j>n)a[i][i]-=1.0;//另外一个方程 
				else a[i][i+j]-=1.0;
			}
		}
	}
	a[n][n]=1.0;//最后的方程 
	a[n][n+1]=0;
	//高斯消元 
	for(int i=1;i<=n;i++){
		int p=i;
		for(int j=i+1;j<=n;j++){//向下查找第j个系数不为0的方程 
			if(fabs(a[j][i])> esp)p=j;
		}
		if(fabs(a[p][i])>esp){
			for(int j=i;j<=n+1;j++)swap(a[i][j],a[p][j]);//把方程移上来 
			for(int j=i+1;j<=n;j++){//向下消元 同时除去其他的系数 
				if(fabs(a[j][i])>esp){
					long double k=a[j][i]/a[i][i];//消元 
					for(int t=i;t<=n+1;t++)a[j][t]-=a[i][t]*k;//系数相减 
				}
			}
		}
	}  
    //回带                 a[i][n+1]就是第i个未知数的解 
    for(int i=n;i>=1;i--){
    	for(int j = i+1;j <= n; j++)if(fabs(a[i][j])>esp){
    		a[i][n+1]-=a[j][n+1]*a[i][j];//用已知的解求未知解 
    	}
    	if(abs(a[i][i])<=esp&&abs(a[i][n+1])>esp){//如果出现矛盾 
    		printf("-1");
    		return 0;
    	}
    	a[i][1+n]/=a[i][i];//求出当前的解 
    }
    
    printf("%.12lf",(double)a[1][1+n]);//输出第一个未知数的解 就是答案 
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值