YTU OJ 3282: 嚮往的氣球
阿新 • • 發佈:2018-12-11
3282: 嚮往的氣球
題目描述
一年一度的計控ACM院賽即將來臨。除了ACMers以外,志願者們也非常的忙碌。他們需要將各種顏色的氣球分配給A掉相應題目的隊伍。現在,所有比賽隊伍的成員都處在一個房間中,這個房間是一個二維座標系,大小為1000行x1000列。 每一個座標對應著空座位或某個參賽隊伍。每一分鐘,志願者們都應該把所有的氣球聚集在一起。志願者將會被告知把氣球送到哪裡。為了保證工作的效率,對於兩個座標(x1,y1)和(x2,y2),如果|x1-x2|不大於k 或者 |y1-y2|不大於k,則這兩個座標的氣球由同一個志願者配送。你能知道最少需要多少志願者,才能配送完所有的氣球嗎?
輸入
第一行包含一個整數T,表示有T組資料。 對於每一組陣列,這裡將有n+1行 第一行:輸入兩個整數n,k; n表示氣球的數量,k表示題目中的k值 接下來的n行中,每一行包含兩個整數r,c。表示氣球應該被送往r行,c列。請注意座標可能會相同。 題目中保證:T<=100,1<=n<=10000,1<=k,r,c<=1000
輸出
對於每一組資料,你需要輸出一行 輸出最少需要的志願者數量
樣例輸入
2 3 5 1 1 10 6 15 20 2 5 1 1 7 7
樣例輸出
1 2
/*
題目要算最少需要幾個志願者,最直接的想法把滿足條件的幾個區域都歸一個志願者; 實在滿足不了的就只能再找另一個志願者++;
所以就要解決兩個問題
1.如何把滿足條件的座標都合併在一起;
2.如果座標都合併在一起了,如何查詢座標是不是一個集合裡的呢?
-->>-->>並查集唄。。。。。
*/
#include<cstdio> #include<iostream> #include<cstdlib> #include<algorithm> #include<cstring> using namespace std; struct P { int r; int c; //int pRank; } p[10010]; P parent[1010][1010]; bool cmp1(P a, P b) { return a.r<b.r; } bool cmp2(P a,P b) { return a.c<b.c; } P findRoot(P pp) { if(parent[pp.r][pp.c].r==pp.r&&parent[pp.r][pp.c].c==pp.c) return pp; else return parent[pp.r][pp.c]=findRoot(parent[pp.r][pp.c]); } void unionNode(P p1,P p2) { P g1=findRoot(p1); P g2=findRoot(p2); if(g1.r==g2.r&&g1.c==g2.c) { return ; } //if(g1.pRank<g2.pRank) parent[g1.r][g1.c]=g2; /*else { parent[g2.r][g2.c]=g1; if(g1.pRank==g2.pRank) g1.pRank++; }*/ } int main() { int t,n,m,k,rr,cc; cin>>t; for(int i=0;i<t;i++) { memset(parent,0,sizeof(parent)); cin>>n>>k; for(int i=0;i<n;i++) { cin>>rr>>cc; p[i].r=rr; p[i].c=cc; //p[i].pRank=0; parent[rr][cc].r=rr; parent[rr][cc].c=cc; } sort(p,p+n,cmp1); for(int i=0; i<n-1; i++) { if(p[i+1].r-p[i].r<=k) { unionNode(p[i],p[i+1]); } } sort(p,p+n,cmp2); for(int i=0;i<n-1;i++) { if(p[i+1].c-p[i].c<=k) { unionNode(p[i],p[i+1]); } } int a=0; for(int i=1;i<=1001;i++) { for(int j=1;j<=1001;j++) { if(parent[i][j].r==i&&parent[i][j].c==j) a++; } } cout<<a<<endl; } return 0; }