poj 1389 Area of Simple Polygons

完全相同与poj 1511,可以直接离散化来做,也可以”离散化+线段树+扫描线“搞定,方正方法不止一种;

离散化的程序:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
#define N 1002
int t;
int serch(int *arr,int key)
{
    int low,high,mid;
    low=0,high=2*t-1;
    while(low<=high)
    {
        mid=(low+high)/2;
        if(key==arr[mid])return mid;
        if(key>arr[mid])low=mid+1;
        else high=mid-1;
    }
    return 0;
}
int main()
{
    int x[2*N],y[2*N],s[N][4];
    bool xy[2*N][2*N];
    while(1)
    {
    t=0;
    while(scanf("%d%d%d%d",&s[t][0],&s[t][1],&s[t][2],&s[t][3])!=EOF)
    {
        if(s[t][0]==-1&&s[t][1]==-1&&s[t][2]==-1&&s[t][3]==-1)break;
        else t++;
    }
    if(t)
    {
        int k=0;
        for(int i=0;i<t;i++)
        {
            x[k]=s[i][0];
            y[k]=s[i][1];
            k++;
            x[k]=s[i][2];
            y[k]=s[i][3];
            k++;
        }
        sort(x,x+k);
        sort(y,y+k);
        memset(xy,false,sizeof(xy));
        for(int i=0;i<t;i++)
        {
            int f1=serch(x,s[i][0]);
            int f2=serch(x,s[i][2]);
            int f3=serch(y,s[i][1]);
            int f4=serch(y,s[i][3]);
            for(int j=f1;j<f2;j++)
            {
                for(int k=f3;k<f4;k++)
                {
                    xy[j][k]=true;
                }
            }
        }
        int area=0;
        for(int i=0;i<2*t;i++)
        {
            for(int j=0;j<2*t;j++)
            {
                area+=(x[i+1]-x[i])*(y[j+1]-y[j])*xy[i][j];
            }
        }
        printf("%d\n",area);
        continue;
    }
    else return 0;
    }
    return 0;
}
离散化+线段树+扫描线的程序:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
#define N 1002
struct SegTree
{
    int l,r,mid;
    int c,m;
}tree[N*3];
struct Line
{
    bool flag;
    int y1,y2,x;
}line[2*N];
int t;
int y[2*N];
bool cmp(Line a,Line b)
{
    return a.x<b.x;
}
void BulidTree(int root,int l,int r)        //建立线段树
{
    tree[root].l=l;
    tree[root].r=r;
    tree[root].c=0;
    tree[root].m=0;
    tree[root].mid=(l+r)/2;
    if(l+1==r)return;
    BulidTree(2*root,l,tree[root].mid);
    BulidTree(2*root+1,tree[root].mid,r);
}
int serch(int *arr,int num,int key)
{
    int low,high,mid;
    low=0,high=num-1;
    while(low<=high)
    {
        mid=(low+high)/2;
        if(arr[mid]==key)return mid;
        if(key>arr[mid])low=mid+1;
        else high=mid-1;
    }
    return 0;
}
void Updata(int root)
{
    if(tree[root].c>0)tree[root].m=y[tree[root].r]-y[tree[root].l];
    else if(tree[root].r-tree[root].l==1)tree[root].m=0;
    else tree[root].m=tree[2*root].m+tree[2*root+1].m;
}
void insert(int root,int l,int r)
{
    if(l<=tree[root].l&&tree[root].r<=r)
    {
        tree[root].c++;
        Updata(root);
        return;
    }
    if(tree[root].r-tree[root].l==1)return;
    if(l<tree[root].mid)insert(2*root,l,r);
    if(r>tree[root].mid)insert(2*root+1,l,r);
    Updata(root);
}
void Delet(int root,int l,int r)
{
    if(l<=tree[root].l&&tree[root].r<=r)
    {
        tree[root].c--;
        Updata(root);
        return;
    }
    if(tree[root].r-tree[root].l==1)return;
    if(l<tree[root].mid)Delet(2*root,l,r);
    if(r>tree[root].mid)Delet(2*root+1,l,r);
    Updata(root);
}
int main()
{
    while(1)
    {
        int x1,y1,x2,y2;
        int ty[2*N];
        t=0;
        while(scanf("%d%d%d%d",&x1,&y1,&x2,&y2)!=EOF)
        {
            if(x1==-1&&y1==-1&&x2==-1&&y2==-1)break;
            else
            {
                line[2*t].flag=true;
                line[2*t].x=x1;
                line[2*t].y1=y1;
                line[2*t].y2=y2;

                line[2*t+1].flag=false;
                line[2*t+1].x=x2;
                line[2*t+1].y1=y1;
                line[2*t+1].y2=y2;

                ty[2*t]=y1;
                ty[2*t+1]=y2;
                t++;
            }
        }
        if(t)
        {
            t<<=1;
            sort(line,line+t,cmp);
            sort(ty,ty+t);
            y[0]=ty[0];
            int num;
            for(int i=num=1;i<t;i++)
            {
                if(ty[i]!=ty[i-1])
                {
                    y[num++]=ty[i];     //将纵坐标去重成功
                }
            }
            BulidTree(1,0,num-1);         //建立线段树
            int area=0;
            for(int i=0;i<t;i++)
            {
                int l=serch(y,num,line[i].y1);
                int r=serch(y,num,line[i].y2);
                if(line[i].flag)insert(1,l,r);
                else Delet(1,l,r);
                area+=tree[1].m*(line[i+1].x-line[i].x);
            }
            printf("%d\n",area);
            continue;
        }
        else return 0;
    }
    return 0;
}

其实,感觉都是模式化的。只要多写多练多体会,这些还是能够很好的掌握的!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值