標籤:des blog http io os ar for sp 資料
http://www.lydsy.com/JudgeOnline/problem.php?id=1013
只要列出方程組就能套高斯來解了。
顯然距離相等,所以開不開平方都無所謂。
b表示圓心,可列
sigma((x[i][j]-b[j])^2)=sigma((x[i+1][j]-b[j])^2)
化簡得
sigma(2*b[j]*(x[i+1][j]-x[i][j]))=sigma(x[i+1][j]^2-x[i][j]^2)
然後就得到n個等式,而且題目保證有解,就套高斯就行了。
第一次學高斯消元啊,其實就是在一個係數矩陣(叫做啥增廣矩陣),每一次將第i行的下邊的第i列的係數全部消除,最後得到一個倒三角矩陣,然後回代就是了。
也就是說
1 2 3
2 3 4
的矩陣,當前行在1,我們首先要消掉第二行的第一列,就相當於第一行*2(這個2就是2/1得來),然後第二行減去第一行。
就是消元嘛。。
在這裡第i行i列的元素叫做主要元素,而我們就是要將所有大於第i行的行將這一列的通過主要元素消除。這裡需要注意,主要元素不要為0,且不要很小,要不然會嚴重影響精度(就是如果很小的話無法體現分母了)。那麼我們在每一次消元時,要找第i列最大的,然後和當前行交換,這樣能得到最大的主要元素。
高斯中判斷無解和無限解的問題還待研究。
#include <cstdio>#include <cstring>#include <cmath>#include <string>#include <iostream>#include <algorithm>#include <queue>using namespace std;#define rep(i, n) for(int i=0; i<(n); ++i)#define for1(i,a,n) for(int i=(a);i<=(n);++i)#define for2(i,a,n) for(int i=(a);i<(n);++i)#define for3(i,a,n) for(int i=(a);i>=(n);--i)#define for4(i,a,n) for(int i=(a);i>(n);--i)#define CC(i,a) memset(i,a,sizeof(i))#define read(a) a=getint()#define print(a) printf("%d", a)#define dbg(x) cout << (#x) << " = " << (x) << endl#define printarr2(a, b, c) for1(_, 1, b) { for1(__, 1, c) cout << a[_][__]; cout << endl; }#define printarr1(a, b) for1(_, 1, b) cout << a[_] << ‘\t‘; cout << endlinline const int getint() { int r=0, k=1; char c=getchar(); for(; c<‘0‘||c>‘9‘; c=getchar()) if(c==‘-‘) k=-1; for(; c>=‘0‘&&c<=‘9‘; c=getchar()) r=r*10+c-‘0‘; return k*r; }inline const int max(const int &a, const int &b) { return a>b?a:b; }inline const int min(const int &a, const int &b) { return a<b?a:b; }const int N=15;double A[N][N], a[N][N];int n;void gauss() {for1(i, 1, n-1) {int pos=i;for1(j, i+1, n) if(abs(A[pos][i])<abs(A[j][i])) pos=j;for1(j, 1, n+1) swap(A[i][j], A[pos][j]);for1(j, i+1, n) {double y=A[j][i]/A[i][i];for1(k, i, n+1) A[j][k]-=y*A[i][k];}}for3(i, n, 1) {for1(j, i+1, n) A[i][n+1]-=A[j][n+1]*A[i][j];A[i][n+1]/=A[i][i];}}int main() {read(n);for1(i, 1, n+1) for1(j, 1, n) scanf("%lf", &a[i][j]);for1(i, 1, n) {for1(j, 1, n) A[i][j]=2*(a[i+1][j]-a[i][j]);for1(j, 1, n) A[i][n+1]+=a[i+1][j]*a[i+1][j]-a[i][j]*a[i][j];}gauss();for1(i, 1, n-1) printf("%.3lf ", A[i][n+1]); printf("%.3lf\n", A[n][n+1]);return 0;}
Description
有一個球形空間產生器能夠在n維空間中產生一個堅硬的球體。現在,你被困在了這個n維球體中,你只知道球面上n+1個點的座標,你需要以最快的速度確定這個n維球體的球心座標,以便於摧毀這個球形空間產生器。
Input
第一行是一個整數,n。接下來的n+1行,每行有n個實數,表示球面上一點的n維座標。每一個實數精確到小數點後6位,且其絕對值都不超過20000。
Output
有且只有一行,依次給出球心的n維座標(n個實數),兩個實數之間用一個空格隔開。每個實數精確到小數點後3位。資料保證有解。你的答案必須和標準輸出一模一樣才能夠得分。
Sample Input2
0.0 0.0
-1.0 1.0
1.0 0.0Sample Output0.500 1.500HINT
資料規模:
對於40%的資料,1<=n<=3
對於100%的資料,1<=n<=10
提示:給出兩個定義:
1、 球心:到球面上任意一點距離都相等的點。
2、 距離:設兩個n為空白間上的點A, B的座標為(a1, a2, …, an), (b1, b2, …, bn),則AB的距離定義為:dist = sqrt( (a1-b1)^2 + (a2-b2)^2 + … + (an-bn)^2 )
Source
【BZOJ】1013: [JSOI2008]球形空間產生器sphere(高斯消元)