高斯消元做题1

本文介绍最基本的高斯消元的两道例题

P4035 [JSOI2008]球形空间产生器

题目思路

有平方肯定需要消掉

使得第\(i\)个式子减去第\(i+1\)个式子使得,然后进行化简就是普通的高斯消元了

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
#define fi first
#define se second
#define debug printf("aaaaaaaaaaa\n");
const int maxn=1e2+5,inf=0x3f3f3f3f,mod=51123987,mul=233;
const ll INF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-7;
int n;
double a[maxn][maxn],b[maxn][maxn],x[maxn];
void gs(int n){
    for(int i=1,pos;i<=n;i++){
        for(pos=i;pos<=n;pos++){
            if(fabs(a[pos][i])>eps){
                break;
            }
        }
        if(pos==n+1){
            printf("No Solution\n");
            return ;
        }
        for(int j=1;j<=n+1;j++){
            swap(a[pos][j],a[i][j]);
        }
        for(int j=i+1;j<=n;j++){
            double p=a[j][i]/a[i][i];
            for(int k=i;k<=n+1;k++){
                a[j][k]-=p*a[i][k];
            }
        }
    }
    for(int i=n;i>=1;i--){
        x[i]=a[i][n+1];
        for(int j=i+1;j<=n;j++){
            x[i]-=x[j]*a[i][j];
        }
        x[i]/=a[i][i];
    }
    for(int i=1;i<=n;i++){
        printf("%.3f ",x[i]);
    }
}

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n+1;i++){
        for(int j=1;j<=n;j++){
            scanf("%lf",&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];
        }
    }
    gs(n);
    return 0;
}

P5027 Barracuda

题目思路

这个就是枚举哪个是不好的,然后剩下的进行高斯消元即可

复杂度\(O(n^4)\)

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
#define fi first
#define se second
#define debug printf("aaaaaaaaaaa\n");
const int maxn=1e2+5,inf=0x3f3f3f3f,mod=51123987,mul=233;
const ll INF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-7;
int n;
double a[maxn][maxn],b[maxn][maxn],x[maxn];
int gs(int n){
    for(int i=1,pos;i<=n;i++){
        for(pos=i;pos<=n;pos++){
            if(fabs(a[pos][i])>eps){
                break;
            }
        }
        if(pos==n+1){
            return -1;
        }
        for(int j=1;j<=n+1;j++){
            swap(a[pos][j],a[i][j]);
        }
        for(int j=i+1;j<=n;j++){
            double p=a[j][i]/a[i][i];
            for(int k=i;k<=n+1;k++){
                a[j][k]-=p*a[i][k];
            }
        }
    }
    for(int i=n;i>=1;i--){
        x[i]=a[i][n+1];
        for(int j=i+1;j<=n;j++){
            x[i]-=x[j]*a[i][j];
        }
        x[i]/=a[i][i];
    }
    double ma=-1;
    int cnt=0,pos=1;
    for(int i=1;i<=n;i++){
        if(x[i]<eps) return -1;
        if((x[i]-(int)x[i])>eps) return -1;
        if(abs(x[i]-ma)<eps){
            cnt++;
        }else if(x[i]>ma){
            ma=x[i];
            pos=i;
            cnt=1;
        }
    }
    if(cnt>1){
        return -1;
    }else{
        return pos;
    }

}

int main(){
    scanf("%d",&n);
    for(int i=1,m,val;i<=n+1;i++){
        scanf("%d",&m);
        for(int j=1,x;j<=m;j++){
            scanf("%d",&x);
            b[i][x]=1;
        }
        scanf("%d",&val);
        b[i][n+1]=val;
    }
    int flag=0;
    int ans=0;
    for(int i=1;i<=n+1;i++){
        int cnt=0;
        for(int j=1;j<=n+1;j++){
            if(i==j) continue;
            cnt++;
            for(int k=1;k<=n+1;k++){
                a[cnt][k]=b[j][k];
            }
        }
        int x=gs(n);
        if(x!=-1){
            flag++;
            ans=x;
        }
    }
    if(flag!=1){
        printf("illegal\n");
    }else{
        printf("%d\n",ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/hunxuewangzi/p/15542058.html