problem-1001

来源:互联网 发布:网络安全工程师学习 编辑:程序博客网 时间:2024/06/05 18:40

题义:给定若干(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;}

0 0
原创粉丝点击