1. 程式人生 > 其它 >【題解】P4035 [JSOI2008]球形空間產生器

【題解】P4035 [JSOI2008]球形空間產生器

【題解】P4035 [JSOI2008]球形空間產生器

一點說明:實際上,我本來不打算把我寫的這些跟題目本身有關的總結放到部落格裡的(而是丟在洛谷剪下板裡),主要是因為,我寫的那些總結是給自己看的不是給別人看的,應該說我寫的總結甚至不能算是一篇題解。題解的終極目標是要教會別人,而不是僅僅讓自己懂。現在網上有太多低質量題解,題解作者為了自己明白一道題,寫一篇類似總結的東西,然而他寫的內容很多都是一些高度濃縮非人類語言,甚至有些題解只有程式碼。。。然後放在網上,美其名曰“題解”,最後的結果是自己懂了,但是讀題解的人更加迷惑。我自己就深受其害。我並不確定我寫的那些東西是否能夠做到讓別人明白,所以並不打算放到網上。

但是由於在寫一些關於高斯消元的總結,需要用到一些例題的講解過程,所以我在反覆斟酌之後,發了這一篇看起來“應該算的上題解”的題解。如果有什麼不理解的地方,請在評論區留言,我會改正完善自裁的。


題目連結:P4035 [JSOI2008]球形空間產生器

思路分析:

  • 首先根據題意可以直接列出來這個式子:\(\sum \limits_{j=1}^{n}(a_{i,j}-x_j)^2=C\)。其中 \(i \in [1,n+1]\),球面上的第 \(i\) 個點是 \((a_{i,1},a_{i,2},…,a_{i,n})\),球心的在 \(n\) 維平面上的座標是\((x_1,x_2,x_3,…,x_n)\)

    。所以該方程組實際上是 \(n+1\)\(n\) 元二次方程組,\(C\) 是未知常數。

  • 考慮我們現在要達成的目標:

    1. 由於 \(C\) 是未知的,所以我們要消掉 \(C\)

    2. 由於高斯消元本身並非二次方程組,所以我們要想辦法降次,把它變為一次

    所以我們下來要做的,都是要圍繞這兩個目標進行。

    先考慮消元

    想到我們在學方程的時候的消元辦法:可以把兩個一樣的方程做差。

    在這道題中,由於我們的方程組的所有方程的右邊都是 \(C\),我們就可以考慮讓相鄰兩個方程做差。就可以轉化成 \(n\)\(n\) 元一次方程組:

    \[ \sum \limits_{j=1}^{n}[(a_{i,j}-x_j)^2-(a_{{i+1},j}-x_j)^2]=0(i=1,2,3,…,n) \]

    兩個易錯點

    1. 由於 \(j\) 表示的是維度,而不是點編號,所以 \(j\) 的下標是從 1 開始而不是 0 開始,這一點甚至在李煜東的《演算法競賽進階指南》中都錯了,千萬不要把 \(i\)\(j\) 搞反。我剛開始也只是單純接受書上說的沒經過思考,是 dbxxx 大佬發現的(%他)

    2. 相鄰兩個方程對應的只是 \(i\) 的變化,\(j\) 並沒有改變。

    再考慮降次

    看到這麼複雜的式子,我們應該先把它展開:

    \[ \sum \limits_{j=1}^{n}({a_{i,j}}^2-{a_{i+1,j}}^2-2x_j(a_{i,j}- a_{i+1,j}))=0(i=1,2,3,…,n) \]

    觀察式子可以發現,式子中的 \(a_{i,j}^2-a_{i+1,j}^2\) 實際上是常數,也就是說,上述式子中跟未知數 \(x_j\) 有關的項根本不含二次項

    所以我們直接通過移項,將變數放在等號左邊,常數項放在等號右邊,以達到降次的目的:

    \[ \sum \limits_{j=1}^{n}2(a_{i,j}-a_{i+1,j})x_j=\sum\limits_{j=1}^{n}({a_{i,j}}^2-{a_{{i+1},j}}^2)(i=1,2,3,…,n) \]

    於是,這就變成了一個線性方程組,直接用高斯消元求解即可!

程式碼實現: