1. 程式人生 > >HihoCoder 1570 : 小Hi與法陣(簡單幾何)

HihoCoder 1570 : 小Hi與法陣(簡單幾何)

height sqrt i++ 小數 一行 需要 iostream 頂點 images

描述

小Hi喜歡大,而小Ho喜歡小。他們所在的城市(視為二維平面)有N座法陣。現在他們各選三座法陣,以三座法陣為頂點組成三角形,並站在所選三角形的重心位置;二人選擇的法陣可以有相同的。小Hi選擇面積最大的三角形,小Ho選擇面積最小的三角形。若有多個面積相同且符合他們要求的三角形,小Hi選擇重心橫坐標最大的,若重心橫坐標相同,則選擇重心縱坐標最大的;小Ho選擇重心橫坐標最小的,若重心橫坐標相同,則選擇重心縱坐標最小的。

現在兩人需要見面,兩人均可以在城市裏以不超過U的速度向任意方向移動,問他們兩個最少經過多長時間可以相會?

例如下圖中的例子,共六座法陣,分別為A,B,C,D,E,F,則小Hi位於三角形ABC的重心G上,小Ho位於三角形DEF的重心H上。

技術分享圖片

註意兩人選擇的三座法陣必須能組成三角形,不能是共線的。

輸入

輸入包含多組數據,第一行包含一個數字T,代表數據組數。1<=T<=10

對於每組數據:

第一行為兩個整數N、U,分別代表法陣數量和最高移動速度。3<=N<=50,1<=U<=10

接下來N行,每行兩個整數Xi和Yi,代表第i所法陣的橫縱坐標。-300<=Xi,Yi<=300。

輸入保證法陣位置不同。

輸出

對於每組數據,輸出一行,包含一個數字,代表相會時間,四舍五入保留到小數點後2位。

樣例輸入

1
3  1
0 10
-10 0
10 5

樣例輸出

0.00

  • 面積可以用向量法或者海倫公式求。
  • 判斷是否共線,不能直接用斜率相同。解決方案是1,特判y軸相同。2,把除法變為乘法。3,向量法求得的面積為0。
  • 用整數避開浮點數的誤差。
//向量法
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=60;
const int inf=100000000;
int
x[maxn],y[maxn]; int get_S(int i,int j,int k) { return abs((x[j]-x[i])*(y[k]-y[i])-(x[k]-x[i])*(y[j]-y[i])); } int main() { int x1,y1,x2,y2; int Min,Max; int i,j,k,n,u,T; scanf("%d",&T); while(T--){ Min=inf;Max=-inf; x1=0;y1=inf;x2=0;y2=inf; scanf("%d%d",&n,&u); for(i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]); for(i=1;i<=n;i++) for(j=i+1;j<=n;j++) for(k=j+1;k<=n;k++){ int tmp=get_S(i,j,k); if(tmp==0) continue; int tx=(x[i]+x[j]+x[k]),ty=(y[i]+y[j]+y[k]); if(tmp<Min||(tmp==Min&&tx<x1)||(tmp==Min&&tx==x1&&ty<y1)) { Min=tmp;x1=tx;y1=ty;} if(tmp>Max||(tmp==Max&&tx>x2)||(tmp==Max&&tx==x2&&ty>y2)) { Max=tmp;x2=tx;y2=ty;} } double dx=(x1-x2)/3.0,dy=(y1-y2)/3.0; printf("%.2lf\n",sqrt(dx*dx+dy*dy)/u/2.0); }return 0; }

HihoCoder 1570 : 小Hi與法陣(簡單幾何)