寬闊的平原上分散著 $N$ 隻山羊,悠閒地吃著草。沒有兩隻山羊處於同一個位置。山羊很懶,不會移動位置,只偶爾在原地轉身。實際上,牠們都是機器人,不能行走,只能原地旋轉。牠們的鼻子是可以遠端點亮的 LED 燈,眼睛是高效能攝影機,攝影機拍攝的畫面可以遠端即時查看,也可以儲存所需的畫面。山羊能看見自己的鼻子,眼睛還具有透視功能,因此即使山羊在視野中重疊,也能分辨出有多少隻。眼睛的水平視野為 $180^\circ$,位於這 $180^\circ$ 視野邊界上的物體也能看見。
根據位置的不同,有些山羊可以同時看見全部 $N$ 隻山羊,也可能有些山羊無論朝哪個方向都無法同時看見全部 $N$ 隻。例如,下圖有編號為 $0$ 到 $5$ 的六隻山羊,$5$ 號山羊可以同時看見全部六隻,但 $2$ 號山羊無論朝哪個方向都無法同時看見全部六隻。
為了進行一個特殊實驗,選出兩隻各自能夠同時看見全部 $N$ 隻山羊的不同山羊,再從剩下的山羊中任意選一隻。將這三隻山羊的鼻子點亮,使其位置可以從任何地方辨認出來。觀察這三隻山羊眼中的畫面,為每隻山羊儲存一幀能同時看見三隻鼻子點亮的山羊的畫面。依序查看這三幀畫面,在每幀中,給三隻鼻子點亮的山羊以及位於另外兩隻鼻子點亮的山羊之間(包含邊界)的所有山羊加上特殊標記。實驗的目標是,求出 $N$ 隻山羊中三次都被標記的山羊數量。
例如,將六隻山羊中選出的三隻以紅點表示時,下圖展示了從每隻被選山羊的視角看被加上特殊標記的山羊。(這些圖當然並非儲存的畫面本身。)此時,三次都被標記的山羊有 $4$ 隻。
你需要為這個特殊實驗實作以下兩個函式。
void init( int x[], int y[] ):這個函式最先被呼叫,且只呼叫一次。x和y是大小為 $N$ 的陣列(向量)。參數x[0..N-1]和y[0..N-1]分別給出山羊位置的 $x$ 座標和 $y$ 座標。$i$ 號山羊($0\le i\le N-1$)的位置為(x[i], y[i])。int count( int a, int b, int c ):利用給定三隻山羊的座標(x[a], y[a])、(x[b], y[b])、(x[c], y[c]),計算並回傳三次都被標記的山羊數量。
實作細節
你必須提交一個名為 goat.cpp 的檔案,其中應實作以下函式。
void init( int x[], int y[] ); int count( int a, int b, int c );
這些函式應按上文所述運作。當然,你可以定義其他函式供內部使用。提交的程式碼不得進行輸入輸出,也不得存取其他檔案。
評分程式範例
所提供的評分程式按照以下格式讀取輸入。
- 第一行:$N\ Q$,其中 $N$ 為山羊數量,$Q$ 為詢問數量。
- 接下來 $N$ 行,每行:$x\ y$,表示一隻山羊位置的 $x$ 座標和 $y$ 座標。
- 接下來 $Q$ 行,每行:$a\ b\ c$ ($a,b,c$),表示三隻山羊的編號,其中 $0\le a,b,c\le N-1$。
評分程式對每個詢問輸出滿足條件的山羊數量,每個結果占一行。
資料範圍
- $3\le N\le 3000$
- $1\le Q\le 5\times10^6$
- 所有山羊的 $x$ 座標和 $y$ 座標都在 $0$ 到 $10^9$ 之間,包含端點。
子任務
1 (5 分)
- $N\le 500$, $Q\le 10^5$
- 任意三個點都不共線。
2 (17 分)
- $N\le 500$, $Q\le 10^5$
3 (10 分)
- $N\le 500$
- 任意三個點都不共線。
4 (8 分)
- $N\le 500$
5 (29 分)
- 任意三個點都不共線。
6 (31 分)
- 沒有額外限制。
範例
輸入格式 1
6 3 0 0 1 1 2 2 4 3 0 2 2 0 0 5 2 1 3 4 4 1 5
輸出格式 1
4 4 3
下面依序列出範例 1 的函式呼叫及其結果。
| 函式呼叫 | 回傳值 |
|---|---|
init( {0, 1, 2, 4, 0, 2}, {0, 1, 2, 3, 2, 0} ) |
|
count( 0, 5, 2 ) |
4 |
count( 1, 3, 4 ) |
4 |
count( 4, 1, 5 ) |
3 |