HDU 5531 Rebuild 相切的圓們

2021-07-06 08:05:56 字數 2087 閱讀 2783

終於迎來了長春的重現。賽場上太多的遺憾,比賽的時候唯一看都沒看一眼的題就是這個題,太可惜了。連同b題一起,為了搶個fb對不住打重現賽的童鞋們了。。。。。求放過,也不知道這個時候寫題解算不算違規呢哈哈。。。。。。

題意:按順序給出乙個多邊形,以多邊形的每個頂點為圓心作圓,使得任意兩相鄰點對應的圓相切,求所有圓面積總和的最小值。

畫個圖算兩下就出來了,發現只需要對n的奇偶性進行討論即可。

設每個點為pi(0 <= i <= n - 1),對應圓的半徑為ri,pi和p(i + 1)(預設pn為p0)的距離為di,則很顯然我們得到了n個方程:

fi:ri + r(i + 1) = di(0 <= i <= n - 1)。

通過這個方程我們發現,全部加起來除以2即得到了所有ri的和。當n為奇數時,將i為奇數的方程fi相加可以得到r1 + r2 + ...... + r(n - 1)的和,再用總和減去它即得到了r0,也就是說,n為奇數時,這個方程組有唯一解,所以,解出所有的解,只要所有解都非負即可算出答案,如果有負的就impossible。當n為偶數時,i為偶數的方程相加和i為奇數的方程相加的結果應該是一樣的(都等於所有ri之和)。所以先算這兩個和,如果這兩個和不相等,也是impossible。其次,我們從第二個方程起,可以將每個ri都變成與r0相關的式子,這樣,所有圓的面積都可以用r0表示,最後的總面積是關於r0的二次函式,直接求解最小值即可。設ri = ai*r0 + bi,

則r(i + 1) = di - ri = -ai*r0 - bi + di。所以a(i + 1) = -ai,b(i + 1) = - bi + di。a0 = 1,b0 = 0。這樣求出每個ai和bi(可以發現ai只有1和-1

),然後面積和 = pi*sigma(ri^2,0 <= i <= n - 1) = a*r0^2 + b*r0 + c,算出a,b,c的值再根據每個ri的範圍(0 <= ri <= min(di,d(i + 1))求出r0的取值範圍(即維護區間的左右端點),如果區間右端點小於左端點,則無解impossible。否則根據二次函式性質算出區間內最低點即可。

#include #include #include #include #include #include #include #include #include #include #include using namespace std;

const int max = 1e4 + 5;

const double pi = acos(-1.0);

const double eps = 1e-6;

int n, x[max], y[max];

double d[max], r[max];

int sgn(double t)

double f(double a, double b, double c, double t)

void input()

void solve()

r[0] = all/2 - other;

if(sgn(r[0]) < 0)

ans += r[0]*r[0];

for(int i = 1; i < n; i++)

ans += r[i]*r[i];

}printf("%.2lf\n", pi*ans);

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

printf("%.2lf\n", r[i]);

}else

int k = 1;

double b = 0, l = 0, r = d[0];

double a = 1, b = 0, c = 0;

for(int i = 1; i < n; i++)

if(sgn(l - r) > 0)

double mid = -b/(2*a), ans;

if(sgn(l - mid) >= 0)

if(sgn(r - mid) <= 0)

if(sgn(mid - l) >= 0 && sgn(mid - r) <= 0)

printf("%.2lf\n", pi*ans);

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

}}int main()

}



HDU 5531(Rebuild )分析 三分

給定乙個n,代表有n個點,給出n個座標,以每個座標為圓心畫圓。要求 相鄰的兩個點畫的圓必須相切 第i個和第i 1個,及第乙個點和最後乙個點 所有圓的面積之和最小。注 半徑可以為0。如果n為奇數,通過列方程可以知道,那麼就可以直接求r1,然後 r i dist i 1 r i 1 依次把所有的r求出來...

HDU 5531 幾何公式

include include include include using namespace std const int maxn 1e4 5 const double inf 1e20 const double pi acos 1 const double eps 1e 8 struct poi...

HDU 5531 平面幾何 三分

題意是給你n個點,然後要求以每個點為圓心畫乙個圓,使得兩兩相鄰的圓心的圓相切,不相鄰的圓可以相交,如果可以作這樣的圓那麼輸出圓面積和的最小值和,每個圓的半徑,否則輸出impossible。首先我們求出每一條鄰邊的長度,記為l1,l2,l3,ln,假定第乙個圓的半徑為x,那麼我們可以用x表示所有圓的半...