链接:http://acm.hdu.edu.cn/showproblem.php?pid=1264
题意:在一个直角坐标系中给出若干个矩阵对角线两个点的坐标,求所有的矩形所覆盖的面积,x,y范围[0,100],且是整数
这个题分到线段树那类的,但是看了题后感觉范围也比较小,直接数组暴力模拟应该不会超时,结果和所想一样。不过最近在学线段树,还是要慢慢研究线段树的做法,想到后再贴线段树的代码。
#include<stdio.h>
#include<string.h>
#define MAXN 105
#define min(a,b) (a)<(b)?(a):(b)
#define max(a,b) (a)>(b)?(a):(b)
int map[MAXN][MAXN];
int main()
{
int x1,y1,x2,y2;
int i,j,ans=0;
while(scanf("%d%d%d%d",&x1,&y1,&x2,&y2))
{
if(x1==-1||x1==-2)
{
printf("%d\n",ans);
if(x1==-2)
break;
ans=0;
memset(map,0,sizeof(map));
}
else
{
int xs=min(x1,x2),xe=max(x1,x2),ys=min(y1,y2),ye=max(y1,y2);
for(i=xs;i<xe;i++)
for(j=ys;j<ye;j++)
if(!map[i][j])
map[i][j]=1,ans++;
}
}
return 0;
}
线段树扫描线版本,范围太窄就不用离散化了
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 105
#define lch p<<1
#define rch p<<1|1
#define mid (t[p].l+t[p].r)>>1
struct node
{
int l,r;
int cover,dy;
}t[MAXN<<2];
struct segment
{
int x,yd,yu;
int lr;
segment(){}
segment(int x,int yd,int yu,int lr):x(x),yd(yd),yu(yu),lr(lr){}
bool operator < (const segment &a)const
{
return x<a.x;
}
}seg[10005];
void construct(int l,int r,int p)
{
t[p].l=l,t[p].r=r;
t[p].cover=t[p].dy=0;
if(l+1>=r) return ;
int m=mid;
construct(l,m,lch);
construct(m,r,rch);
}
void pushup(int p)
{
if(t[p].cover) t[p].dy=t[p].r-t[p].l;
else if(t[p].l+1==t[p].r) t[p].dy=0;
else t[p].dy=t[lch].dy+t[rch].dy;
}
void modify(int l,int r,int op,int p)
{
if(t[p].l>=l&&t[p].r<=r)
{
t[p].cover+=op;
pushup(p);
return ;
}
if(t[p].l+1==t[p].r) return ;
int m=mid;
if(l<=m) modify(l,r,op,lch);
if(r>=m) modify(l,r,op,rch);
pushup(p);
}
int main()
{
int x1,y1,x2,y2;
int cnt=0;
while(scanf("%d%d%d%d",&x1,&y1,&x2,&y2)!=EOF)
{
if(x1==-1||x1==-2)
{
construct(0,100,1);
sort(seg,seg+cnt);
int ans=0;
for(int i=0;i<cnt-1;i++)
{
modify(seg[i].yd,seg[i].yu,seg[i].lr,1);
ans+=t[1].dy*(seg[i+1].x-seg[i].x);
}
printf("%d\n",ans);
cnt=0;
if(x1==-2) break;
}
else
{
seg[cnt++]=segment(min(x1,x2),min(y1,y2),max(y1,y2),1);
seg[cnt++]=segment(max(x1,x2),min(y1,y2),max(y1,y2),-1);
}
}
return 0;
}