HDU 1264 Counting Squares

来源:互联网 发布:oracle not in 优化 编辑:程序博客网 时间:2024/05/17 03:41

Counting Squares

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 105    Accepted Submission(s): 59

Problem Description
Yourinput is a series of rectangles, one per line. Each rectangle isspecified as two points(X,Y) that specify the opposite corners of arectangle. All coordinates will be integers in the range 0 to 100. Forexample, the line
5 8 7 10
specifies the rectangle who's corners are(5,8),(7,8),(7,10),(5,10).
Ifdrawn on graph paper, that rectangle would cover four squares. Your jobis to count the number of unit(i.e.,1*1) squares that are covered byany one of the rectangles given as input. Any square covered by morethan one rectangle should only be counted once.
 

 

Input
Theinput format is a series of lines, each containing 4 integers. Four-1's are used to separate problems, and four -2's are used to end thelast problem. Otherwise, the numbers are the x-ycoordinates of twopoints that are opposite corners of a rectangle.
 

 

Output
Your output should be the number of squares covered by each set of rectangles. Each number should be printed on a separate line.
 

 

Sample Input
5 8 7 10
6 9 7 8
6 8 8 11
-1 -1 -1 -1
0 0 100 100
50 75 12 90
39 42 57 73
-2 -2 -2 -2
 

 

Sample Output
8
10000
 

 

Source
浙江工业大学第四届大学生程序设计竞赛
 

 

Recommend
JGShining


题目的意思很简单,给定几个长方形,叫你求这些长方形的并起来的面积


本人使用的是离散化+线段树解决的



首先把所有的X坐标排序进行离散化
然后枚举每一个区间(X[i],X[i+1]);
再扫描所有的长方形,如果有长方形能覆盖(X[i],X[i+1]),那么在线段树中插入线段[Y1,Y2] (Y2>Y1)
之后统计该区间内的线段总长度L,ans+=L*(X[i+1]-X[i])


#include<iostream>
#include<algorithm>
using namespace std;
struct Seg
{
    int l,r,val;
}seg[305];
struct Line
{
    int x1,x2,y1,y2;
}line[105];
int X[205],len,llen,MV=0;
int ans,val=0;
void mkseg(int l,int r,int x)
{
    int mid=(l+r)>>1;
    seg[x].l=l;
    seg[x].r=r;
    seg[x].val=0;
    MV=MV>x?MV:x;
    if(r-l==1)
        return;
    mkseg(l,mid,2*x);
    mkseg(mid,r,2*x+1);
}
void ins(int l,int r,int x)
{
    if(x>MV)return;
    if(l<=seg[x].l&&seg[x].r<=r)
    {
        seg[x].val=val;
        return;
    }
    int mid=(seg[x].l+seg[x].r)>>1;
    if(r<=mid)
        ins(l,r,2*x);
    else if(l>=mid)
        ins(l,r,2*x+1);
    else ins(l,mid,2*x),ins(mid,r,2*x+1);
}
void gans(int x)
{
    if(x>MV)return;
    if(seg[x].val==val)
    {
        ans+=(seg[x].r-seg[x].l);
        return;
    }
    gans(2*x);
    gans(2*x+1);
}
int main()
{
    int a,b,c,d,i,j,area;
    bool end=false;
    mkseg(0,100,1);
    while(scanf("%d%d%d%d",&X[0],&a,&X[1],&b)!=EOF)
    {
        if(X[0]==-1)
        {
            puts("0");
            continue;
        }
        if(X[0]==-2)return 0;
        area=0;
        len=2;
        if(X[0]>X[1])swap(X[0],X[1]);
        line[0].x1=X[0];
        line[0].x2=X[1];
        if(a>b){a^=b;b^=a;a^=b;}
        line[0].y1=a;
        line[0].y2=b;
        llen=1;
        while(scanf("%d%d%d%d",&a,&b,&c,&d)!=EOF)
        {
            if(d==-1)break;
            if(d==-2){end=true;break;}
            if(b>d){b^=d;d^=b;b^=d;}
            if(a>c){a^=c;c^=a;a^=c;}
            X[len]=a;
            X[len+1]=c;
            line[llen].x1=a;
            line[llen].x2=c;
            line[llen].y1=b;
            line[llen].y2=d;
            llen++;
            len+=2;
        }
        sort(X,X+len);
        for(i=0;i<len-1;i++)
        {    //X坐标的区间段...
            if(X[i]==X[i+1])continue;
            ++val;
            for(j=0;j<llen;j++)
            {
                if(line[j].x1<=X[i]&&line[j].x2>=X[i+1])ins(line[j].y1,line[j].y2,1);
            }
            ans=0;
            gans(1);
            area+=ans*(X[i+1]-X[i]);
        }
        printf("%d/n",area);
        if(end)return 0;
    }
    return 0;
}

下面是今天写的离散化的,复杂度是o(n^3)居然0ms....

#include<iostream>
#include<algorithm>
using namespace std;
int X[2002],Y[2002],Len,Rlen;
struct Rec
{
    int xlow,xhigh,ylow,yhigh;
}R[1001];
int main()
{
    int ans;
    int i,j,k;
    int x1,y1,x2,y2;
    bool flag=false;
    while(!flag)
    {
        Rlen=1;
        Len=1;
        while(scanf("%d%d%d%d",&x1,&y1,&x2,&y2)!=EOF)
        {
            if(x1==-1&&x2==-1&&y1==-1&&y2==-1)break;
            if(x1==-2&&x2==-2&&y1==-2&&y2==-2){flag=true;break;}
            if(x1>x2)swap(x1,x2);
            if(y1>y2)swap(y1,y2);
            X[Len]=x1;
            X[Len+1]=x2;
            Y[Len]=y1;
            Y[Len+1]=y2;
            R[Rlen].xlow=x1;
            R[Rlen].xhigh=x2;
            R[Rlen].ylow=y1;
            R[Rlen].yhigh=y2;
            Rlen++;
            Len+=2;
        }
        ans=0;
        sort(X+1,X+Len);
        sort(Y+1,Y+Len);
        for(i=1;i<Len-1;i++)
        {
            if(X[i]==X[i+1])continue;
            for(j=1;j<Len-1;j++)
            {
                if(Y[j]==Y[j+1])continue;
                for(k=1;k<Rlen;k++)
                {
                    if(R[k].xlow<=X[i]&&R[k].xhigh>=X[i+1]&&R[k].ylow<=Y[j]&&R[k].yhigh>=Y[j+1])
                    {
                        ans+=(X[i+1]-X[i])*(Y[j+1]-Y[j]);
                        break;
                    }
                }
            }
        }
        printf("%d/n",ans);
    }
    return 0;
}

原创粉丝点击