用线段树+离散化做hdu1264比单纯的离散化更为复杂,但是适用范围也更广,今天看这个看得头都晕了,还是有点细节没有处理好,暂时归类到sloving中,明天再继续研究吧,不是AC代码
大意是离散化所有的x线段,然后将所有的y坐标打成一棵线段树,那么每次遍历到一个x[i-1],x[i]区间时,只要将这个区间长度乘以当前所有被覆盖到的y的总长度就可以得到当前的面积,就这样扫描掉所有的x线段,然后把求得的面积累加就可以得到整个图形的面积了
#include <iostream>
using namespace std;
const int size = 110;
struct STree
{
int l, r;
int check;
int cover;
}stree[2*size];
struct rec
{
int sx, sy, ex, ey;
}a[size];
void creat(int num, int l, int r)
{
stree[num].l = l, stree[num].r = r, stree[num].cover = stree[num].check = 0;
if (l == r)return ;
int mid = (l+r) >> 1;
int p = num << 1;
creat(p, l, mid);
creat(p+1, mid+1, r);
}
void insert(int num, int l, int r, int check)
{
int a = stree[num].l, b = stree[num].r;
if (a == l && b == r){
stree[num].check = check;
if (l != r){
stree[num].cover = (stree[num].r - stree[num].l)*check;
}
else stree[num].cover = check;
}
if (l == r){
stree[num].cover = 1;
return ;
}
int mid = (a+b)>> 1;
int p = num << 1;
if (r <= mid)insert(p, l, r, check);
else
if (l > mid)insert(p+1, l, r, check);
else insert(p, l, mid, check), insert(p+1, mid+1, r, check);
stree[num].cover = stree[p].cover + stree[p+1].cover;
}
bool cmp(int x, int y)
{
return x < y;
}
int main()
{
bool is_finish = false;
int mappx[size];
while (!is_finish){
int ii = 0;
int xx = 0;
int maxxy = -1;
while (scanf("%d%d%d%d", &a[ii].sx, &a[ii].sy, &a[ii].ex, &a[ii].ey)){
if (a[ii].sx == -1)break;
if (a[ii].sx == -1){is_finish = true;break;}
if (a[ii].sx > a[ii].ex)swap(a[ii].sx, a[ii].ex);
if (a[ii].sy > a[ii].ey)swap(a[ii].sy, a[ii].ey);
if (maxxy < a[ii].ey)maxxy = a[ii].ey;
mappx[xx ++] = a[ii].sx, mappx[xx ++] = a[ii].ex,
ii ++;
}
sort(mappx, mappx+xx, cmp);
int sum = 0;
for (int i = 1; i < xx; i ++){
creat(1, 1, maxxy);
if (mappx[i-1] == mappx[i])continue;
for (int j = 1; j < ii; j ++){
if (a[j].sx <= mappx[i-1] && a[j].ex >= mappx[i]){
insert(1, a[j].sy, a[j].ey, 1);
}
}
sum += (mappx[i]-mappx[i-1])*stree[1].cover;
}
printf("%d\n",sum);
if (is_finish)break;
}
return 0;
}