1. 程式人生 > >YTU.3282: 嚮往的氣球

YTU.3282: 嚮往的氣球

3282: 嚮往的氣球

時間限制: 1 Sec  記憶體限制: 128 MB
提交: 172  解決: 41
[提交][狀態][討論版][命題人:acm4302]

題目描述

一年一度的計控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

分析:並查集,引入一個變數p來簡化題目

AC程式碼:

#include<bits/stdc++.h>
using namespace std;
#define maxn 10005
typedef struct{
    int x;
    int y;
    int p;
}ZB;
ZB a[maxn];
int f[maxn];
bool cmp1(ZB a,ZB b)
{
    return a.x<b.x;
}
bool cmp2(ZB a,ZB b)
{
    return a.y<b.y;
}
int findx(int x)
{
    int r=x;
    while(r!=f[r])
    {
        r=f[r];
    }
    return r;
}
int main()
{
    int t;
    int n,k;
    int r,c;
    int ans;
    cin>>t;
    while(t--)
    {
        ans=0;
        cin>>n>>k;
        for(int i=0;i<n;i++)
        {
        cin>>a[i].x>>a[i].y;
        a[i].p=i;
        f[i]=i; 
        }
        sort(a,a+n,cmp1);
        for(int i=1;i<n;i++)
        {
        if(a[i].x-a[i-1].x<=k)
        {
            f[findx(a[i].p)]=findx(a[i-1].p);
            }   
        }
        sort(a,a+n,cmp2);
        for(int i=1;i<n;i++)
        {
            if(a[i].y-a[i-1].y<=k)
            {
                f[findx(a[i].p)]=findx(a[i-1].p);
            }
        }
    for(int i=0;i<n;i++)
    {
        if(f[i]==i)
        ans++;
        }   
    cout<<ans<<endl;
}
return 0;
}

之前一次做的程式碼,感覺繁瑣了許多:

/*
沒考慮好資料範圍,這兩句程式碼坑死我啊....
#define maxx 10010
zb f[maxx][maxx]={0};
*/
#include<iostream>
#include<math.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef struct {
    int r;
    int c;
} zb;
zb a[10000];
zb f[1001][1001];
zb findx(zb x) {
    if(f[x.r][x.c].r==x.r&&f[x.r][x.c].c==x.c)
        return x;
    else
        return f[x.r][x.c]=findx(f[x.r][x.c]);
}
void merge(zb x,zb y) {
    zb fx,fy;
    fx=findx(x);
    fy=findx(y);
//  if(fx.r!=fy.r||fx.c!=fy.c)
//      f[fx.r][fx.c]=fy;
    if(fx.r==fy.r&&fx.c==fy.c)
    {
        return;
    }
    else
    {
        f[fx.r][fx.c]=fy;
    }
}
int cmp1(zb a,zb b) {
    return a.r<b.r;
}
int cmp2(zb a,zb b) {
    return a.c<b.c;
}
int main() {
    int T;
    cin>>T;
    while(T--) {
        int n,k;
        cin>>n>>k;
        int cnt=0;
        memset(f,0,sizeof(f));
        int rr,cc;
        for(int i=0; i<n; i++) {         
            cin>>rr>>cc;
            a[i].r=rr;
            a[i].c=cc;
            f[rr][cc].r=rr;
            f[rr][cc].c=cc;
        }
        sort(a,a+n,cmp1);
        for(int i=0; i<n-1; i++) {
            if(a[i+1].r-a[i].r<=k)
                merge(a[i],a[i+1]);
        }
        sort(a,a+n,cmp2);
        for(int i=0; i<n-1; i++) {
            if(a[i+1].c-a[i].c<=k)
                merge(a[i],a[i+1]);
        }
        for(int i=1; i<=1000; i++) {
            for(int j=1; j<=1000; j++) {
                if(f[i][j].r==i&&f[i][j].c==j)
                    cnt++;
            }
        }
        cout<<cnt<<endl;
    }
    return 0;
}