高斯消元做题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;
}
不摆烂了,写题