HDU 1542 面积并

一道模板题,就是让你求所有的面积。

附上链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542

先上代码,实在看不懂就看我的图...

#include
#include
#include
#include
using namespace std;
const int N = 205;
int n;
double y[N];

struct Line
{
    double x;
    double down,up;
    int flag;
}line[N];
bool cmp(Line a,Line b)
{
    return a.x < b.x;
}
struct Node
{
    double l,r;
    double x;
    int cover;
    bool flag;
}node[N << 2];

void build(int l,int r,int i)
{
    node[i].l = y[l];
    node[i].r = y[r];
    node[i].x = -1;
    node[i].flag= false;
    node[i].cover  = 0;
    if(l+1 == r)
    {
        node[i].flag = true;
        return ;
    }
    int mid =(l + r)/2;
    build(l,mid,i*2);//这里为什么是mid,是因为线段连续呀...第一个坑
    build(mid,r,i*2+1);
 }
 double Insert_query(int i,double x,double l,double r, int flag)
 {
     if(l >= node[i].r || r <= node[i].l) //不重合
     {
         return 0;
     }
     if(node[i].flag)
     {
         if(node[i].cover > 0)
         {
             double ans = 0;
             double pre = node[i].x;
             ans = (x-pre)*(node[i].r - node[i].l);
             node[i].x = x;//平移
             node[i].cover += flag;//改变覆盖边数
             return ans;
         }
         else
         {
             node[i].cover += flag;
             node[i].x = x;
             return 0;
         }
     }
     double ans1,ans2;
     ans1 = Insert_query(i*2,x,l,r,flag);
     ans2 = Insert_query(i*2+1,x,l,r,flag);
     return ans1+ans2;
 }
 int main()
 {
     int n;
     int t = 1;
     while(cin >> n)
     {
         int cnt =0;
         if(n == 0)
            break;
         while(n--)
        {
            double x1,y1,x2,y2;
            cin >> x1 >> y1 >> x2 >> y2;

           y[cnt]=y1;
            line[cnt].x=x1;
            line[cnt].down=y1;
            line[cnt].up=y2;
            line[cnt++].flag=1; //  表示左边线段;

            y[cnt]=y2;
            line[cnt].x=x2;
            line[cnt].down=y1;
            line[cnt].up=y2;
            line[cnt].flag=-1;//表示右边线段
        }
        sort(y,y+cnt+1);//线段树的上下界必须排序
        sort(line,line+cnt+1,cmp);//排序,让线段从左往右依次加入
        build(0,cnt,1);
        double area = 0;
        for(int i = 0;i <= cnt ;i++)//几条边就有几条查询更新操作
        {
            area += Insert_query(1,line[i].x,line[i].down,line[i].up,line[i].flag);
        }
        printf("Test case #%d\n",t++);
        printf("Total explored area: %.2f\n",area);
        cout << endl;//格式 wa了好几发
     }

 }

HDU 1542 面积并_第1张图片

 

 

你可能感兴趣的:(ACM,线段树)