problem-1001

題義:給定若干(1<= n <=5000)組二維座標點,凡是滿足  "x1<= x2 && y1<= y2"的話那麼我們承認這兩個座標是屬於同一個集合中。題目要我們求出這些座標點最少能表示成幾個集合。先將所有的點的信息保存起來,然後選取 x 或者 y 作爲對象進行排序,排序中注意如果兩個點的 x相同,那麼這時候要保持 y有序。這樣做的目的是使得所有集合線性的呈現出來,可以理解爲經過這樣一次排序後,能夠每次從前到後找到一個包含點滿足題義且最多的點集。不會出現正確分離出來的集合在該排列中有元素是逆序的。


代碼:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

struct T
{
    int w,l;
}a[5010];

bool cmp(T a,T b)
{
    if(a.l==b.l)  return a.w<b.w;
    return a.l<b.l;
}

bool vis[5010];

int main()
{
    int cas;
    scanf("%d",&cas);
    while(cas--)
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)  scanf("%d%d",&a[i].l,&a[i].w);

        sort(a,a+n+1,cmp);

        memset(vis,0,sizeof(vis));
        int num=1;//從num開始找
        int w,l;
        int count=0,tt=0;

        while(tt<n)
        {
            vis[num]=1;
            tt++;
            w=a[num].w;
            l=a[num].l;
            bool flag=false;

            for(int i=num+1;i<=n;i++)
            if(!vis[i]&&a[i].l>=l&&a[i].w>=w)
            {
                w=a[i].w;
                l=a[i].l;
                vis[i]=1;
                tt++;
            }
            else if(!vis[i]&&!flag)
            {
                flag=true;
                num=i;
            }

            count++;
        }

        printf("%d\n",count);
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章