【BZOJ】1013: [JSOI2008]球形空間產生器sphere(高斯消元)

來源:互聯網
上載者:User

標籤: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(高斯消元)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.