1. 程式人生 > >cogs 1310. [HAOI2006]聰明的猴子

cogs 1310. [HAOI2006]聰明的猴子

坐標系 spa haoi2006 turn main 描述 fff mat pro

1310. [HAOI2006]聰明的猴子

★ 輸入文件:monkey.in 輸出文件:monkey.out 簡單對比
時間限制:1 s 內存限制:128 MB
【題目描述】

在一個熱帶雨林中生存著一群猴子,它們以樹上的果子為生。昨天下了一場大雨,現在雨過天晴,但整個雨林的地表還是被大水淹沒著,

猴子不會遊泳,但跳躍能力比較強,它們仍然可以在露出水面的部分植物的樹冠上來回穿梭,以找到喜歡吃的果實。

現在,在這個地區露出水面的有N棵樹,假設每棵樹本身的直徑都很小,可以忽略不計。我們在這塊區域上建立直角坐標系,則每一棵樹的位置由其所對應的坐標表示(任意兩棵樹的坐標都不相同)。

在這個地區住著的猴子有M個,下雨時,它們都躲到了茂密高大的樹冠中,沒有被大水沖走。由於各個猴子的年齡不同、身體素質不同,它們跳躍的能力不同。有的猴子跳躍的距離比較遠(當然也可以跳到較近的樹上),而有些猴子跳躍的距離就比較近。這些猴子非常聰明,它們通過目測就可以準確地判斷出自己能否跳到對面的樹上。

任務:現已知猴子的數量及每一個猴子的最大跳躍的距離,還知道露出水面的每一棵樹的坐標,你的任務是統計有多少猴子可以在這個地區露出水面的所有樹冠上覓食。

【輸入格式】

第一行一個整數,表示猴子的個數 M(2<=M<=500)

第二行為M個整數,依次表示猴子的最大跳躍距離(每個整數值在1---1000之間)

第三行為一個整數,表示樹的總棵樹N(2<=N<=1000)

第四行至第N+3行為N棵樹的坐標(橫縱坐標均為整數,範圍為:-1000--1000)

【輸出格式】

輸出只有一行,包括一個整數,表示可以有這個地區的所有樹冠上覓食的猴子數。

【樣例輸入】

4 1 2 3 4 6 0 0 1 0 1 2 -1 -1 -2 0 2 2

【樣例輸出】

3

【提示】

對於40%的數據,保證有2<=N<=100,1<=M<=100

對於100%的數據,保證有2<=N<=1000,1<=M<=500

思路:最小生成樹。

#include<cmath>
#include
<cstdio> #include<iostream> #include<algorithm> using namespace std; int monky[501]; struct q{ int x,y,t; }tree[1001]; int m,n,num,f[1001]; struct p{ int from; int to; double dis; }c[1000001]; int cmp(p a1,p a2){ return a1.dis<a2.dis; } int find(int x){ if(f[x]!=x) f[x]=find(f[x]); return f[x]; } int main(){ freopen("monkey.in","r",stdin); freopen("monkey.out","w",stdout); cin>>m; for(int i=1;i<=m;i++) cin>>monky[i]; cin>>n; for(int i=1;i<=n;i++){ cin>>tree[i].x>>tree[i].y; tree[i].t=i; } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ c[++num].from=tree[i].t; c[num].to=tree[j].t; c[num].dis=sqrt(pow(tree[i].x-tree[j].x,2)+pow(tree[i].y-tree[j].y,2)); } stable_sort(c+1,c+1+num,cmp); stable_sort(monky+1,monky+1+m); int u,l=0; for(int i=1;i<=n;i++) f[i]=i; for(int i=1;i<=num;i++){ if(l==n-1) break; if(find(c[i].from)!=find(c[i].to)){ f[find(c[i].from)]=find(c[i].to); l++; u=c[i].dis; } } int tot=0; for(int i=1;i<=m;i++) if(monky[i]>=u) tot++; cout<<tot; return 0; }

cogs 1310. [HAOI2006]聰明的猴子