time limit: 10 sec memory limit: 162 mb
submit: 1587 solved: 669
[submit][status][discuss]
有n個圓盤從天而降,後面落下的可以蓋住前面的。求最後形成的封閉區域的周長。看下面這副圖, 所有的紅
色線條的總長度即為所求.
第一行為1個整數n,n<=1000
接下來n行每行3個實數,ri,xi,yi,表示下落時第i個圓盤的半徑和圓心座標.
最後的周長,保留三位小數
21 0 0
1 1 0
10.472
分析:一開始的思路是每增加乙個圓盤,看它能覆蓋到被計入答案的區域,答案減掉這個長度.這個想法似乎是可行的,但是維護每個圓盤哪些位置被覆蓋了非常困難.
換個思路,考慮每個圓盤對答案的貢獻:原周長-被後來的圓盤覆蓋的周長.實際上後面一部分就是要求周長並,可以將圓拆成一條線段,規定乙個起點和終點.但是這樣的話還要求兩個圓的交點,不好處理.乙個比較好的方法是記錄被覆蓋部分的圓心角,放到[0,2π)這個區間裡.利用兩個圓心的極角和圓心角可以比較容易地計算.圓心角可以通過餘弦定理得到.需要注意的是左右端點<0和≥2π的情況.
還要判斷兩圓是否是包含/相離關係.
最後怎麼求周長並?先把弧度並給求出來,乘上半徑就是了.具體方法是在左端點+1,右端點-1,用cnt統計+1,-1的和,如果cnt > 0,則ans -= 第i個弧度-第i-1個弧度.ans初始化為2π.(有點複雜,結合**更好理解)
#include #include#include
#include
#include
using
namespace
std;
const
double pi = acos(-1.0),eps = 1e-8
;int
n,tot;
double
ans,sum;
struct
node
e[1010
];struct
node2
p[10010
];double
d(node a,node b)
bool
cmp(node2 a,node2 b)
intmain()
if (dist > fabs(e[i].r - e[j].r) && dist <= e[i].r +e[j].r) //必須要相交不能分離
if (l >= 0 && r <= 2 *pi)
else
if (l < 0
)
else}}
if(flag)
continue
; ans += e[i].r * 2 *pi;
if (!tot)
continue
; sort(p + 1,p + 1 +tot,cmp);
for(int j = 1; j <= tot; j++)
} printf(
"%.3lf\n
",ans);
return0;
}
1043 HAOI2008 下落的圓盤
time limit 10 sec memory limit 162 mb submit 1725 solved 743 submit status discuss 有n個圓盤從天而降,後面落下的可以蓋住前面的。求最後形成的封閉區域的周長。看下面這副圖,所有的紅 色線條的總長度即為所求.第一行為1個...
BZOJ1043 HAOI2008 下落的圓盤
每個圓盤只會受到後邊的圓盤的影響 所以算一下每個圓盤和後邊的圓盤相交的圓心角,然後求個並即可 可以用餘弦定理 複雜度n 2 log n 注意特判沒有交 include include include include include include include include include in...
bzoj1043 HAOI2008 下落的圓盤
題目鏈結 有n個圓盤從天而降,後面落下的可以蓋住前面的。求最後形成的封閉區域的周長。直接模擬,求出當前圓盤與之前的所有的圓盤的交點,用極角表示,模擬結束後求出每個圓盤未被覆蓋的角度即可。include include include include include include using nam...