輸入第一行包含乙個正整數 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...