bzoj1013

本来是打算这两天一口气刷完poj的6到2-sat的,但昨天的模拟赛被一道题高斯消元直接虐了3个半小时没调出来,后来发现自己的高斯消元的板子就是错的= =。。

今天决定更新一下板子,就参照着黄学长的博客打了一下这道题WA了几遍总算AC了,没什么大问题。

照例丢链接.

这道题题目大意是说给你一个n维空间球上的n+1个点,让你求球心坐标。只要处理一下输入就变成了一道高斯消元的模板题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
double gs[20][20];
double f[20];
int n;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>f[i];
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
double a;
cin>>a;
gs[i][j]=2*a-2*f[j];
gs[i][n+1]+=a*a;
gs[i][n+1]-=f[j]*f[j];
}
//对于读入的处理:
//我们通过n个坐标列距离公式,拆开再合并可以列出n个多项式
//再通过剩下的那个坐标构建等式,移项消元构建方程。
for(int i=1;i<=n;i++)
{
int big=0,mn;
for(int j=1;j<=n;j++)
if(fabs(gs[i][j])>big&&gs[i][j]!=0)
{
big=gs[i][j];
mn=j;
}
if(mn!=i)
for(int j=1;j<=n+1;j++)
swap(gs[i][j],gs[mn][j]);
for(int j=1;j<=n;j++)
{
if(j==i)continue;
double a=gs[j][i]/gs[i][i];
for(int k=1;k<=n+1;k++)
gs[j][k]-=gs[i][k]*a;
}
}
for(int i=1;i<n;i++)
printf("%.3lf ",gs[i][n+1]/gs[i][i]);
printf("%.3lf",gs[n][n+1]/gs[n][n]);
return 0;
}