給定平面上n個點(x_1,y_1),...,(x_n,y_n)(x1,y1),...,(xn,yn),找出2個半徑相同的圓r_1r1和r_2r2,覆蓋給定的n個點,且半徑最小。
設計乙個演算法,計算出所求最小覆蓋雙圓 r_1r1和 r_2r2的半徑。
輸入有多個測試例項。每個例項的第1行中給出正整數n,n<1000,表示平面上有n個點。
接下來的n行中每行給出2個實數(x, y),-100000≤x≤100000,-100000≤y≤100000。
最後一行有乙個0表示結束。
對於每組資料,輸出最小的符合題意的圓的半徑,保留兩位小數。
輸入 #1
3
0.00 0.00輸出 #11.00 0.00
0.00 4.00
10 0.00 0.00
0.00 3.00
1.00 6.00
2.00 2.00
3.00 5.00
5.00 3.00
6.00 3.00
9.00 5.00
10.00 5.00
11.00 3.00
0
0.50
3.05對於100%的資料,n<=1000n<=1000,|x_i|,|y_i|<=100000∣xi∣,∣yi∣<=100000,(t<=10t<=10)
【題目大意】
n個點,現在給兩個半徑相同的圓去覆蓋,求最小半徑
【解題思路】
我們需要盡量可能的減少重複的點,即同時被兩個圓覆蓋的點
所以我們二分列舉這個中間點,讓乙個圓覆蓋一部分
使點沒有重複的被覆蓋
一般情況下,我們直接按 x 排序二分
選擇半徑更大的一邊,然後繼續二分
但是這不行
因為這樣實際上是用一根垂直於 x 軸的直線分兩邊的點
而這個直線可能會有一定斜率
所以這個中間點的查詢就是乙個問題
二分列舉中間的分界點,因為通過圖可知
兩個圓總會關於一條直線對稱
兩圓不相交時是一條,兩圓相交時是他們的交線
我們需要一條直線將所有點分成兩半
但是正像上面所說,是被交線分開的
所以兩邊的點並不會一定被這根線分成兩半
於是我們列舉這根直線的斜率,同時為了更好的排序
我們直接旋轉座標系
旋轉座標系的過程參見線性代數
旋轉這一步我覺得是這道題的關鍵,而其他題解都沒有太說明
注意:對於變數的使用,要注意之前他是否被變更過
除錯**的時候可以通過調整檢視順序達到更高的效率
(先看main ---> 順序往下看)
#include#includeview code#include
#include
using
namespace
std;
const
int maxn = 2*1e3 + 5
;const
double inf =1e18 ;
const
double an = 1.0 / 180 * acos(-1
);const
double eps = 1e-9
;const
double si = sin(an), co =cos(an);
intn;
double reps()
struct
v v(
double a, double
b) :x(a), y(b) {}
v
operator+(const v&b) const
v
operator-(const v&b) const
bool
operator
double
operator*(const v&b) const
double
operator^(const v&b) const
//叉乘
v operator*(double b) const
v
operator/(double b) const
void rota()
v rot()
double len()
}p[maxn],o;
typedef v p;
struct
l friend p cross(l a, l b)
//求交點
};p circle(p a,p b, p c)
//求圓心
p s[maxn];
int sgn(double x)
double solve(int l,int
r) }
}return
r1;}
intmain()
double ans =inf;
///double cnt = 180;
for (int _ = 1; _ <= 181; _++)
for (int i = 1; i <= n; i++)
p[i].rota();
}printf(
"%.2lf\n
", sqrt(ans));
}return0;
}
紀念我寫完的第一道黑題
FJOI2015 金幣換位問題
桌子上有2n 2個位置,其中前n個位置放著n個正面朝上的硬幣,接下來n個位置放著反面朝上的硬幣,後面兩個位置為空。每次操作可以將任意兩個相鄰的硬幣順序不變地移動到空位上,那麼至少要多少次操作可以將硬幣移成正反相間 正面的硬幣在第乙個,最後兩個還是空 例如 當n 4時,有一組合法解如下 1111000...
FJOI2015 火星商店問題
線段樹分治。以時間軸建立線段樹,每乙個線段樹節點,存放 l,r 時間內,有影響的操作1,建立可持久化trie樹,trie樹以商店位置為root,就可以支援商店的區間查詢,然後將操作0,按照商店位置排序,進行線段樹分治,每次到乙個節點,先把操作0插入trie樹,然後把所有當前時間記憶體的有影響的操作1...
題解 FJOI2015火星商店問題
好幾天之前做的題目了,一直想寫一下部落格也沒騰出時間來,今天趕緊把坑給填上呼呼呼 這道題首先如果只考慮每個商店中沒有時間限制的物品時,我們只需要使用一棵可持久化trie樹來維護區間內的異或最大值即可,這樣我們可以把兩部分的問題分離開來。之後我們再考慮有時間限制與編號限制的情況下,該怎樣做?無腦做法線...