poj 3168 Barn Expansion 平面扫描+线段相交问题

来源:互联网 发布:win7服务器端口开放 编辑:程序博客网 时间:2024/05/22 13:36
http://poj.org/problem?id=3168
题意:给你n个矩形,矩形之间只能是完全隔离或者刚好接触,且没有嵌套关系,判断这些矩形中不与
其他任何矩形相接触的个数
ac代码:
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <vector>
    #include <queue>
    #include <map>
    #include <algorithm>
    #include <set>
    using namespace std;
    #define MM(a) memset(a,0,sizeof(a))
    typedef long long ll;
    typedef unsigned long long ULL;
    const int mod = 1000000007;
    const double eps = 1e-10;
    const int inf = 0x3f3f3f3f;
    const int big=50000;
    int max(int a,int b) {return a>b?a:b;};
    int min(int a,int b) {return a<b?a:b;};

    struct edgex{
    int y1,y2,x,id;
    }ex[50005];

    struct edgey{
    int x1,x2,y,id;
    }ey[50005];

    int n,a1,a2,b1,b2,used[25005];

    void add_edgex(int i)
    {
    ex[i]=edgex{b1,b2,a1,i};
    ex[i+n]=edgex{b1,b2,a2,i};
    }

    void add_edgey(int i)
    {
    ey[i]=edgey{a1,a2,b1,i};
    ey[i+n]=edgey{a1,a2,b2,i};
    }

    bool cmpx(edgex a,edgex b)
    {
    if(a.x!=b.x)
    return a.x<b.x;
    return a.y1<b.y1;
    }

    bool cmpy(edgey a,edgey b)
    {
    if(a.y!=b.y)
    return a.y<b.y;
    return a.x1<b.x1;
    }

    int jiaox(int i,int j)
    {
    //printf("//3\n");
    //printf("%d %d",ex[i].x,ex[j].x);
    if((ex[i].x==ex[j].x)&&ex[i].y2>=ex[j].y1)
    {
    ex[j].y2=max(ex[j].y2,ex[i].y2);
    return 1;
    }
    return 0;
    }

    int jiaoy(int i,int j)
    {
    //printf("//4\n");
    if(ey[i].y==ey[j].y&&ey[i].x2>=ey[j].x1)
    {
    ey[j].x2=max(ey[j].x2,ey[i].x2);
    return 1;
    }
    return 0;
    }

    void solve()
    {
    memset(used,0,sizeof(used));
    sort(ex+1,ex+2*n+1,cmpx);
    sort(ey+1,ey+2*n+1,cmpy);

    for(int i=1;i<=2*n-1;i++)
    if(jiaox(i,i+1))
    used[ex[i].id]=used[ex[i+1].id]=1;

    for(int i=1;i<=2*n-1;i++)
    if(jiaoy(i,i+1))
    used[ey[i].id]=used[ey[i+1].id]=1;
    //printf("//2\n");

    int res=0;
    for(int i=1;i<=n;i++)
    if(!used[i])
    res++;
    printf("%d\n",res);
    }

    int main()
    {
    while(~scanf("%d",&n))
    {
    for(int i=1;i<=n;i++)
    {
    scanf("%d %d %d %d",&a1,&b1,&a2,&b2);
    add_edgex(i);
    add_edgey(i);
    }

    solve();
    }
    return 0;
    }

题目分析:从x和y方向两个方向进行拆边就好,分两个方向进行判断,但是注意下面wa的代码错就错在
自己没有考虑到[1,10]   [2,5]  [7,9]这个情况,因为第一个区间可以完全覆盖第二个区间甚至直接与第三个区间相交
而此时第二哥区间则并没有与第三个区间相交;
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <vector>
    #include <queue>
    #include <map>
    #include <algorithm>
    #include <set>
    using namespace std;
    #define MM(a) memset(a,0,sizeof(a))
    typedef long long ll;
    typedef unsigned long long ULL;
    const int mod = 1000000007;
    const double eps = 1e-10;
    const int inf = 0x3f3f3f3f;
    const int big=50000;
    int max(int a,int b) {return a>b?a:b;};
    int min(int a,int b) {return a<b?a:b;};

    struct edgex{
    int y1,y2,x,id;
    }ex[25005];

    struct edgey{
    int x1,x2,y,id;
    }ey[25005];

    int n,cnt,a1,a2,b1,b2,num[25005];

    void add_edgex(int i)
    {
    ex[i]=edgex{b1,b2,a1,i};
    ex[i+n]=edgex{b1,b2,a2,i};
    }

    void add_edgey(int i)
    {
    ey[i]=edgey{a1,a2,b1,i};
    ey[i+n]=edgey{a1,a2,b2,i};
    }

    bool cmpx(edgex a,edgex b)
    {
    if(a.x!=b.x)
    return a.x<b.x;
    return a.y1<b.y1;
    }

    bool cmpy(edgey a,edgey b)
    {
    if(a.y!=b.y)
    return a.x1<b.x1;
    return a.y<b.y;
    }

    int jiaox(int i,int j)
    {
    //printf("//3\n");
    //printf("%d %d",ex[i].x,ex[j].x);
    if(ex[i].x==ex[j].x&&ex[i].y2>=ex[j].y1&&ex[i].y1<=ex[j].y2)
    return 1;
    return 0;
    }

    int jiaoy(int i,int j)
    {
    //printf("//4\n");
    if(ey[i].y==ey[j].y&&ey[i].x2>=ey[i+1].x1&&ey[i].x1<=ey[j].x2)
    return 1;
    return 0;
    }

    void solve()
    {
    memset(num,0,sizeof(num));
    sort(ex,ex+2*cnt+1,cmpx);
    sort(ey,ey+2*cnt+1,cmpy);

    for(int i=1;i<=2*cnt-1;i++)
    if(jiaox(i,i+1))
    {
    num[ex[i].id]--;
    num[ex[i+1].id]--;
    }

    for(int i=1;i<=2*cnt-1;i++)
    if(jiaoy(i,i+1))
    {
    num[ey[i].id]--;
    num[ey[i+1].id]--;
    //printf("//2\n");
    }

    }

    void ans()
    {
    int res=0;
    for(int i=1;i<=n;i++)
    if(num[i]>=0)
    res++;
    printf("%d\n",res);
    }

    int main()
    {
    while(~scanf("%d",&n))
    {
    cnt=0;
    for(int i=1;i<=n;i++)
    {
    scanf("%d %d %d %d",&a1,&b1,&a2,&b2);
    add_edgex(++cnt);
    add_edgey(cnt);
    }

    solve();
    ans();
    }
    return 0;
    }



原创粉丝点击