zoukankan      html  css  js  c++  java
  • 高斯消元

    板子

    题目

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #define maxn 110
    using namespace std;
    template<typename T>
    inline void read(T &x){
        x=0;bool flag=0;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') flag=1;
        for(;isdigit(c);c=getchar()) x=x*10+(c^48);
        if(flag) x=-x;
    }
    
    double eps=1e-8;
    int n;
    double a[maxn][maxn];
    bool no,many;
    
    void gauss(){
        for(int i=1;i<=n;i++){
            int maxi=i;
            for(int j=i+1;j<=n;j++){
                if(fabs(a[j][i])>fabs(a[maxi][i])) maxi=j;
            }
            for(int j=1;j<=n+1;j++) swap(a[maxi][j],a[i][j]);
            if(fabs(a[i][i])<eps) continue;
            double tmp=a[i][i];//后面a[i][i]会变的,所以不能直接除以a[i][i],必须拿tmp存一下 
            for(int j=1;j<=n+1;j++) a[i][j]/=tmp;
            for(int j=1;j<=n;j++){
                if(i==j) continue;
                double tmp=a[j][i];
                for(int k=1;k<=n+1;k++) a[j][k]-=a[i][k]*tmp;
            }
        }
        for(int i=1;i<=n;i++){
            int cnt=0;
            for(int j=1;j<=n+1;j++) if(fabs(a[i][j])<eps) cnt++;
            if(cnt==n&&fabs(a[i][n+1])>=eps) no=1;
            if(cnt==n+1) many=1;
            
        }
    	if(no||many) return ;
        for(int i=n-1;i;i--)
            for(int j=i+1;j<=n;j++)
                a[i][n+1]-=a[j][n+1]*a[i][j];
    }
    
    int main(){
        read(n);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n+1;j++)
                read(a[i][j]);
        gauss();
        if(no){
            cout<<"No Solution"<<endl;
            return 0;
        }
        if(many){
            cout<<"No Solution"<<endl;
            return 0;
        }
        for(int i=1;i<=n;i++) printf("%.2f
    ",fabs(a[i][n+1])<eps?0:a[i][n+1]);
        return 0;
    }
    

    例题

    Luogu P2455线性方程组

    题目

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #define maxn 60
    using namespace std;
    template<typename T>
    inline void read(T &x){
        x=0;bool flag=0;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') flag=1;
        for(;isdigit(c);c=getchar()) x=x*10+(c^48);
        if(flag) x=-x;
    }
    
    double eps=1e-8;
    int n;
    double a[maxn][maxn];
    bool no,many;
    bool no_flag,inf_flag;
    
    void gauss(){
        for(int i=1;i<=n;i++){
            int maxi=i;
            for(int j=i+1;j<=n;j++){
                if(fabs(a[j][i])>fabs(a[maxi][i])) maxi=j;
            }
            for(int j=1;j<=n+1;j++) swap(a[maxi][j],a[i][j]);
            if(fabs(a[i][i])<eps) continue;
            double tmp=a[i][i];//后面a[i][i]会变的,所以不能直接除以a[i][i],必须拿tmp存一下 
            for(int j=1;j<=n+1;j++) a[i][j]/=tmp;
            for(int j=1;j<=n;j++){
                if(i==j) continue;
                double tmp=a[j][i];
                for(int k=1;k<=n+1;k++) a[j][k]-=a[i][k]*tmp;
            }
        }
        for(int i=1;i<=n;i++){
            int cnt=0;
            for(int j=1;j<=n+1;j++) if(fabs(a[i][j])<eps) cnt++;
            if(cnt==n&&fabs(a[i][n+1])>=eps) no=1;
            if(cnt==n+1) many=1;
            
        }
    	if(no||many) return ;
        	for(int i=n-1;i;i--)
                for(int j=i+1;j<=n;j++)
                    a[i][n+1]-=a[j][n+1]*a[i][j];
    }
    
    int main(){
        read(n);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n+1;j++)
                read(a[i][j]);
        gauss();
        if(no){
            cout<<-1<<endl;
            return 0;
        }
        if(many){
            cout<<0<<endl;
            return 0;
        }
        for(int i=1;i<=n;i++) printf("x%d=%.2f
    ",i,fabs(a[i][n+1])<eps?0:a[i][n+1]);
        return 0;
    }
    

    Luogu P4035球形空间产生器

    题目

    #include<iostream>
    #include<cmath> 
    #include<cstdio>
    #include<cstdlib>
    #define maxn 20
    #define ll long long
    using namespace std;
    template<typename T>
    inline void read(T &x){
        x=0;bool flag=0;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') flag=1;
        for(;isdigit(c);c=getchar()) x=x*10+(c^48);
        if(flag) x=-x;
    }
    
    const int eps=1e-8;
    int n;
    double a[maxn][maxn],b[maxn][maxn];
    bool no,many;
    
    void gauss(){
        for(int i=1;i<=n;i++){
            int maxi=i;
            for(int j=i+1;j<=n;j++){
                if(fabs(a[j][i])>fabs(a[maxi][i])) maxi=j;
            }
            for(int j=1;j<=n+1;j++) swap(a[maxi][j],a[i][j]);
            if(fabs(a[i][i])<eps) continue;
            double tmp=a[i][i];//后面a[i][i]会变的,所以不能直接除以a[i][i],必须拿tmp存一下 
            for(int j=1;j<=n+1;j++) a[i][j]/=tmp;
            for(int j=1;j<=n;j++){
                if(i==j) continue;
                double tmp=a[j][i];
                for(int k=1;k<=n+1;k++) a[j][k]-=a[i][k]*tmp;
            }
        }
        for(int i=1;i<=n;i++){
            int cnt=0;
            for(int j=1;j<=n+1;j++) if(fabs(a[i][j])<eps) cnt++;
            if(cnt==n&&fabs(a[i][n+1])>=eps) no=1;
            if(cnt==n+1) many=1;
            
        }
    	if(no||many) return ;
        for(int i=n-1;i;i--)
            for(int j=i+1;j<=n;j++)
                a[i][n+1]-=a[j][n+1]*a[i][j];
    }
    
    int main(){
    	read(n);
    	for(int i=1;i<=n+1;i++)
    		for(int j=1;j<=n;j++)
    			cin>>b[i][j];
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=n;j++) {
    			a[i][j]=2*(b[i][j]-b[i+1][j]);
    			a[i][n+1]+=b[i][j]*b[i][j]-b[i+1][j]*b[i+1][j];
    		}
    	}
    	gauss();
    	for(int i=1;i<=n;i++) printf("%.3f ",fabs(a[i][n+1])<eps?0:a[i][n+1]);
    	printf("
    ");
    	return 0;
    }
    

    Luogu P4111小Z的房间

    题目
    矩阵树定理,关于这个的blog先咕着吧~

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #define maxn 110
    #define int long long
    using namespace std;
    template<typename T>
    inline void read(T &x){
        x=0;bool flag=0;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') flag=1;
        for(;isdigit(c);c=getchar()) x=x*10+(c^48);
        if(flag) x=-x;
    }
    
    const int mod=1e9;
    int n,m,b[maxn][maxn],mp[maxn][maxn],cnt,ans=1;
    char a[maxn][maxn];
    
    void add(int x,int y){
    	mp[x][x]++;mp[y][y]++;mp[x][y]--;mp[y][x]--;
    }
    
    void gauss(){
    	for(int i=1;i<=cnt;i++){
    		for(int j=i+1;j<=cnt;j++){
    			while(mp[j][i]){
    				int tmp=mp[i][i]/mp[j][i];
    				for(int k=i;k<=cnt;k++) mp[i][k]=(mp[i][k]-(mp[j][k]*tmp+mod)%mod+mod)%mod;
    				for(int k=1;k<=cnt;k++) swap(mp[i][k],mp[j][k]);
    				ans*=-1;
    			}
    		}
    		(ans*=mp[i][i])%=mod;
    	}
    }
    
    signed main(){
    	read(n),read(m);
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++){
    			cin>>a[i][j];
    			if(a[i][j]=='.') b[i][j]=++cnt;
    		}
    	cnt--;
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++){
    			if(a[i][j]=='.'){
    				if(a[i+1][j]=='.') add(b[i][j],b[i+1][j]);
    				if(a[i][j+1]=='.') add(b[i][j],b[i][j+1]);
    			}
    		}		
    	gauss();
    	cout<<(ans+mod)%mod<<endl;
    	return 0;
    } 
    

    Luogu P3317重建

    题目
    仍然事矩阵树定理,咕~

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #define maxn 210
    using namespace std;
    template<typename T>
    inline void read(T &x){
        x=0;bool flag=0;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') flag=1;
        for(;isdigit(c);c=getchar()) x=x*10+(c^48);
        if(flag) x=-x;
    }
    //
    //double eps=1e-6;
    //int n,cnt=100;
    //double g[maxn][maxn],mp[maxn][maxn],ans=1;
    
    //void pre(int x,int y,double p){
    //	mp[x][y]-=p/(1-p);
    //	mp[x][x]+=p/(1-p);
    //}
    
    //void gauss(){
    //	for(int i=1;i<=cnt;i++){
    //		int maxi=i;
    //		for(int j=i+1;j<=cnt;j++){
    //			if(fabs(mp[j][i])>fabs(mp[maxi][i])) maxi=j;
    //		}
    //		if(maxi!=i){
    //			for(int j=1;j<=cnt;j++) swap(mp[maxi][j],mp[i][j]);
    //			ans*=-1; 
    //		}
    ////		for(int j=i+1;j<=cnt;j++){
    ////			if(fabs(mp[j][i])>fabs(mp[i][i])){
    ////				for(int k=1;k<=cnt;k++)  swap(mp[i][k],mp[j][k]);
    ////				ans*=-1;
    ////			}
    ////		}
    //		if(fabs(mp[i][i]<eps)){//
    //			ans=0;return ;//
    //		}//
    //		for(int k=i+1;k<=cnt;k++){
    //			double t=mp[k][i]/mp[i][i];
    //			for(int j=i;j<=cnt;j++) mp[k][j]-=mp[i][j]*t;
    //		}
    //		ans*=mp[i][i];
    //	}
    ////	for(int i=1;i<=cnt;i++) ans*=mp[i][i];
    //}
    
    //int main(){
    //	read(n);
    //	for(int i=1;i<=n;i++){
    //		for(int j=1;j<=n;j++){
    //			cin>>g[i][j];
    //			g[i][j]+=eps;
    //			pre(i,j,g[i][j]);
    //			if(i<j) ans*=(1-g[i][j]);
    //		}	
    //	}
    ////	cout<<"*"<<ans<<endl;
    //	cnt=n-1;
    //	gauss();
    //	printf("%.3Lf
    ",fabs(ans));
    //	return 0;
    //}
    
    double eps=1e-6;
    long double z[111][111];
    int nh=100;
    double f=1;
    
    double gauss(){
    	for(int i=1;i<=nh;i++){
    		for(int j=i;j<=nh;j++){
    			if(fabs(z[j][i])>fabs(z[i][i])){
    				f=-f;
    				for(int k=1;k<=nh;k++)swap(z[j][k],z[i][k]);
    			}
    		}
    		if(fabs(z[i][i])<=eps)return 0;
    		for(int j=i+1;j<=nh;j++)	{
    			double x=z[j][i]/z[i][i];
    			for(int k=1;k<=nh;k++){
    				z[j][k]-=z[i][k]*x;
    			}
    		}
    	}
    	for(int i=1;i<=nh;i++){
    		f*=z[i][i];
    	}
    	return f;
    }
    
    void qadx(int f,int t,long double pb){
        z[f][t]-=pb/(1-pb);
        z[f][f]+=pb/(1-pb);
    }
    
    signed main(){
    	int n;
    	cin>>n;
    	long double tmp;
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=n;j++){
    			cin>>tmp;
    			tmp+=eps;
    			qadx(i,j,tmp);
    			if(i<j)f*=(1-tmp);
    		}
    	}
    	nh=n-1;
    	cout<<gauss()<<endl;
    	return 0;
    }
    
  • 相关阅读:
    js 去除金额的千位分隔符
    vue中的iviewUI导出1W条列表数据每次只导出2000条的逻辑
    js取整数、取余数的方法
    http协议
    vue 项目安装sass的依赖包
    浅析vue的双向数据绑定
    闭包
    Top 20 NuGet packages for captcha
    IIS URL Rewrite Module的防盗链规则设置
    IIS URL Rewrite – Installation and Use
  • 原文地址:https://www.cnblogs.com/DReamLion/p/14799354.html
Copyright © 2011-2022 走看看