計算幾何 訊號覆蓋

2021-06-05 06:25:28 字數 2842 閱讀 9241

輸入第一行包含乙個正整數 n, 表示房子的總數。接下來有 n 行,分別表示每乙個房子的位置。對於 i = 1, 2, .., n, 第i 個房子的座標用一對整數 xi和yi來表示,中間用空格隔開。

輸出檔案包含乙個實數,表示平均有多少個房子被訊號所覆蓋,需保證輸出結果與精確值的絕對誤差不超過0.01。

4 0 2

4 4

0 0

2 0

3.500

3.5, 3.50, 3.500, … 中的任何乙個輸出均為正確。此外,3.49, 3.51,

3.499999,…等也都是可被接受的輸出。

【資料範圍】

100%的資料保證,對於 i = 1, 2, .., n, 第 i 個房子的座標(xi, yi)為整數且

–1,000,000 ≤ xi, yi ≤ 1,000,000. 任何三個房子不在同一條直線上,任何四個房子不

在同乙個圓上;

40%的資料,n ≤ 100;

70%的資料,n ≤ 500;

100%的資料,3 ≤ n ≤ 1,500。

直接暴力o(n^4)顯然超時,所以作以下轉化:

可以看出,每三個點所在的圓至少包含三個點,對答案的貢獻為3;而每多包含乙個點,對答案就多貢獻1。

所有包含關係必定可以轉化為乙個乙個的四邊形,凸四邊形對答案的貢獻為14,凹四邊形對答案的貢獻為13。

問題轉化為求有多少個凸四邊形和凹四邊形。

這兩類四邊形的數目之和一定為c(n, 4),而凹四邊形的個數顯然好求一些,即為求有多少個三角形中包含一點。

那麼列舉中間點x,將其它點按極角排序,統計包含這個點的三角形有多少個即可。

進一步轉化,設沒有包含中間點的個數為x,那麼包含該中間點的三角形的個數為p = c(n - 1, 3) - x。

統計x的方法:列舉其中一條線xi,再移動另一條(此時這條線的移動是單調的),保證這兩條線的夾角剛好180°,那麼兩條線間的點任選兩個作為目標三角形的頂點(三角形的第三點為當前列舉的線的端點i)即可。

設凸四邊形的個數為q,則q = c(n, 4) - p。

答案為(14q + 13p) / c(n, 3),經化簡,即為(2q + p) / c(n, 3) + 3。

accode:

#include #include #include #include #include using std::complex;

const char fi = "signaling.in";

const char fo = "signaling.out";

const int maxn = 1510;

const double zero = 1e-8;

typedef complex vec;

typedef long long int64;

vec p[maxn], tmp[maxn << 1];

int n;

int64 p;

void init_file()

inline int getint()

do res = (res << 3) + (res << 1) + tmp - '0';

while (isdigit(tmp = getchar()));

return sgn ? res : -res;

}void readdata()

return;

}#define otp(a, b) \

(real(a) * imag(b) - imag(a) * real(b))

inline int cmp(const void *a, const void *b)

inline void calc(const int x)

return;

}inline int64 c(const int64 n, const int64 m)

void work()

int main()

#undef otp

第二次做:

#include #include #include #include #define cross(a, b) \

(((a).x) * ((b).y) - ((b).x) * ((a).y))

typedef long long int64;

const int maxn = 1510;

struct vec

vec(int64 x, int64 y): x(x), y(y) {}

vec operator-(const vec &b)

};vec p[maxn], tmp[maxn << 1];

int64 n, p;

inline int64 getint()

do res = (res << 3) + (res << 1) + tmp - '0';

while (isdigit(tmp = getchar()));

return sgn ? res : -res;

}inline int cmp(const void *a, const void *b)

inline void calc(int x)

return;

}inline int64 c(int64 n, int64 m)

int main()

for (int i = 0; i < n; ++i) calc(i);

printf("%.3lf", (double)((c(n, 4) << 1) - n

* c(n - 1, 3) + p) / c(n, 3) + 3);

return 0;

}#undef cross

雷達覆蓋 ssl 1232 計算幾何

以雷達心為圓心的半圓形雷達覆蓋範圍有多個點 雷達可旋轉,求最多覆蓋數 含在邊界的 列舉點作為雷達的分界線,用叉積判斷左右兩邊點數量的多少,找乙個最優值。可以先把在半徑之外的點排除 var x,y array 1.10000 of longint sx,sy longint ans longint n...

LuoguP1742最小圓覆蓋 計算幾何

一道模板題吧,wa了好久 開始以為是凸包 旋轉卡殼 等等結果才發現有錯。果然模板不可以亂yy 正解 一看名字就知道,先要把輸入的點打亂,使其隨機化,作用就是降低複雜度,後面講。然後就是從第乙個點開始列舉點 i i 如果當前的列舉的點在圓內部,就繼續不用管,否者就以該點為圓心半徑為0開始列舉 i ro...

P1742 最小圓覆蓋(計算幾何)

體驗過 o n 3 過 10 5 嗎?快來體驗一波當 wys 的快感吧 qaq 設 begina1 x b1 y c1 a2 x b2 y c2 end 其中 a1,a2,b1,b2,c1,c2 為已知量 由 式得 x frac 帶入 式並化簡得 y frac 分子分母同時乘以 a2 得 y fra...