現有乙個[0,0]到[10,10]的方格仔,已知這裡面有一點火源,但你不知道其確切位置 你初始在(0,0) 每次移動到下乙個點並告知你距離火源和上一次比較是更近還是更遠或者same。對於每次移動你需要給出目前火源可能在的區域面積。
每次找到lst與cur點的中垂線,顯然hotter的一邊計入答案與原先剩下的面積半平面交
求中垂線:
中點為mid,法向量fa,中垂線向量(mid,end) end = mid+fa;
vector qaq;
qaq.x = cur.x - lst.x,qaq.y = cur.y - lst.y;
vector fa = get_fa(qaq);
point mid;
mid.x = (cur.x + lst.x)/2.0;
mid.y = (cur.y + lst.y)/2.0;
point end = mid + fa;//mid~end中垂線!
求法向量
vector get_fa(vector y)
else if(!dcmp(y.y - 0))
else
return fa;
}
法向量求出來後需要根據目前法向量的方向與hotter/colder判斷是否需要調整法向量方向(因為我們cut是取向量左半部分)
判斷現在法向量與cur點的關係:
bool compare(point a,point b,point c)
//判斷cur點與直線的關係 cur點做軸!
bool vis = compare(mid,end,cur);
這裡要注意same表示火源在中垂線上,不再存在可行性區域,至此往後0.00
#include#include#include#includeusing namespace std;
const double eps = 1e-8;
const double pi = acos(-1.0);
const double inf = 1.0 * 0x3f3f3f3f;
const int maxn = 305;
int n,m;
char s[maxn];
struct point
}a[maxn],p[maxn],c[maxn];
typedef point vector;
struct line
line(point a,point b)
}l[maxn];
struct node;
int dcmp(double x)
//運算子過載
vector operator + (vector a, vector b)
vector operator - (vector a, vector b)
vector operator * (vector a, double p)
bool operator == (const point &a, const point &b)
double dot(vector a, vector b)
double cross(vector a, vector b)
double dis(point a,point b)
bool compare(point a,point b,point c)
point ist_lp(line a,double a2,double b2,double c2)
node get_abc(line x)
vector get_fa(vector y)
else if(!dcmp(y.y - 0))
else
return fa;
}void cut(double a,double b,double c)//<=0:p[i]點在平移後的直線的左邊 √
else,a,b,c);
} if(a * p[i + 1].x + b * p[i + 1].y + c < 0),a,b,c);//那得給整個點吧
}} }
for(int i = 1;i <= cnt; i++) p[i] = c[i];
p[0] = c[cnt];
p[cnt + 1] = c[1];//p存的是上一次cut完剩下的點 環陣列
m = cnt;
}double s_core()
if(dcmp(ans) < 0) ans *= -1.0;
return ans / 2.0;
}void init()
int main()
vector qaq;
qaq.x = cur.x - lst.x,qaq.y = cur.y - lst.y;
vector fa = get_fa(qaq);
point mid;
mid.x = (cur.x + lst.x)/2.0;
mid.y = (cur.y + lst.y)/2.0;
point end = mid + fa;//mid~end中垂線!
//調整法向量角度!!! 以保證半平面取左邊
bool vis = compare(mid,end,cur);
if((vis && s[0] == 'c') || (!vis && s[0] == 'h'))
//求每次還剩的可行性區域
node now = get_abc(line(mid,end));
cut(now.a,now.b,now.c);
if(m >= 3) printf("%.2f\n",s_core());
else
lst = cur;
} return 0;
}
POJ 3525 半平面交
題意 求凸包內切圓最大半徑 題解 二分半徑,將凸包所有邊往凸包內平移這麼半徑長度,看平移後是否能圍成凸包.file main.cpp author swordholy created on 2011年3月25日,下午7 56 求凸包內切圓最大半徑 include include include in...
POJ 1755 Triathlon 半平面交
看的這裡 題意 鐵人三項比賽,給出 個人進行每一項的速度vi,ui,wi 對每個人判斷,通過改變3項比賽的路程,是否能讓該人獲勝 嚴格獲勝 思路 題目實際上是給出了n個式子方程,ti ai x bi y ci z 0 i n 要判斷第i個人能否獲勝,即判斷不等式組 tj ti 0,0 j n j i...
POJ 3384 Feng Shui 半平面交
題目給出兩個圓和乙個多邊形 問是否能讓兩個圓在多邊形內。並且覆蓋的面積最大 圓的半徑為r,我們則讓多邊形的每條邊都往內部退r距離。然後求半平面交得出的點集中,最遠的兩個點則是兩圓的圓心即可 include include include include include include include...