Hdu 1542 Atlantis + Hdu 1255 覆盖的面积 (线段树矩形面积并)
2013-05-25 15:18
411 查看
用线段树解决矩形面积并的问题。
从以下链接学习,并参考了代码:http://www.cnblogs.com/ka200812/archive/2011/11/13/2247064.html
目前只能写出朴素写法,dp写法还没有学会。
Hdu 1542
Hdu 1255
从以下链接学习,并参考了代码:http://www.cnblogs.com/ka200812/archive/2011/11/13/2247064.html
目前只能写出朴素写法,dp写法还没有学会。
Hdu 1542
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int N=110; struct LINE { int flag; //1表示左边,-1表示右边 double x,y_down,y_up; void Get (int _flag,double _x,double _y_down,double _y_up) { flag=_flag; x=_x; y_down=_y_down; y_up=_y_up; } bool operator < (const LINE &a) const { return x<a.x; } }line[2*N]; struct TREE { double y_down, y_up; double x; int cover; //用以表示加进线段树中的线段次数 bool flag; //flag==true表示达到了叶子节点 }tree[1000*N]; int n; double x1,y1,x2,y2; double y[2*N]; void Build (int t,int left,int right) { tree[t].x = -1; //-1表示该区间已经没有线段 tree[t].cover = 0; //表示该区间上有多少条线段;左边线段加进去则++,右边线段加进去则-- tree[t].y_down = y[left]; tree[t].y_up = y[right]; tree[t].flag = false; if (left+1==right) { tree[t].flag=true; return; } int mid=(left+right)>>1; Build(2*t,left,mid); Build(2*t+1,mid,right); } double Insert (int t,double x,double left,double right,int flag) //flag表示为左边还是右边 { if (right<=tree[t].y_down || left>=tree[t].y_up) return 0; if (tree[t].flag) if (tree[t].cover > 0) //递归到了叶子节点 { double temp_x=tree[t].x; double ans=(x-temp_x)*(tree[t].y_up - tree[t].y_down); tree[t].x=x; //定位上一次的x tree[t].cover+=flag; return ans; } else { tree[t].cover += flag; tree[t].x = x; return 0; } double ans1, ans2; ans1 = Insert(2*t, x, left, right, flag); ans2 = Insert(2*t+1, x, left, right, flag); return ans1+ans2; } int main () { #ifdef ONLINE_JUDGE #else freopen("read.txt","r",stdin); #endif int Cas=0,i; while (scanf("%d",&n),n) { int id=1; for (i=1;i<=n;i++) { scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); y[id]=y1; line[id++].Get(1,x1,y1,y2); y[id]=y2; line[id++].Get(-1,x2,y1,y2); } sort (y+1,y+id);//把所有的纵坐标按从小到大排序 sort (line+1,line+id); Build (1,1,id-1); double ans=0; for (i=1;i<id;i++) ans += Insert(1, line[i].x, line[i].y_down, line[i].y_up, line[i].flag); printf("Test case #%d\nTotal explored area: %.2f\n\n",++Cas,ans); } return 0; }
Hdu 1255
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int N=1005; struct LINE { int flag; //1表示左边,-1表示右边 double x,y_down,y_up; void Get (int _flag,double _x,double _y_down,double _y_up) { flag=_flag; x=_x; y_down=_y_down; y_up=_y_up; } bool operator < (const LINE &a) const { return x<a.x; } }line[2*N]; struct TREE { double y_down, y_up; double x; int cover; //用以表示加进线段树中的线段次数 bool flag; //flag==true表示达到了叶子节点 }tree[1001*N]; int n; double x1,y1,x2,y2; double y[2*N]; void Build (int t,int left,int right) { tree[t].x = -1; //-1表示该区间已经没有线段 tree[t].cover = 0; //表示该区间上有多少条线段;左边线段加进去则++,右边线段加进去则-- tree[t].y_down = y[left]; tree[t].y_up = y[right]; tree[t].flag = false; if (left+1==right) { tree[t].flag=true; return; } int mid=(left+right)>>1; Build(2*t,left,mid); Build(2*t+1,mid,right); } double Insert (int t,double x,double left,double right,int flag) //flag表示为左边还是右边 { if (right<=tree[t].y_down || left>=tree[t].y_up) return 0; if (tree[t].flag) if (tree[t].cover > 1) //覆盖2次或以上 { double temp_x=tree[t].x; double ans=(x-temp_x)*(tree[t].y_up - tree[t].y_down); tree[t].x=x; //定位上一次的x tree[t].cover+=flag; return ans; } else { tree[t].cover += flag; tree[t].x = x; return 0; } double ans1, ans2; ans1 = Insert(2*t, x, left, right, flag); ans2 = Insert(2*t+1, x, left, right, flag); return ans1+ans2; } int main () { #ifdef ONLINE_JUDGE #else freopen("read.txt","r",stdin); #endif int T; scanf("%d",&T); while (T--) { int id=1,i; scanf("%d",&n); for (i=1;i<=n;i++) { scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); y[id]=y1; line[id++].Get(1,x1,y1,y2); y[id]=y2; line[id++].Get(-1,x2,y1,y2); } sort (y+1,y+id);//把所有的纵坐标按从小到大排序 sort (line+1,line+id); Build (1,1,id-1); double ans=0; for (i=1;i<id;i++) ans += Insert(1, line[i].x, line[i].y_down, line[i].y_up, line[i].flag); printf("%.2lf\n",ans); } return 0; }
相关文章推荐
- HDU - 1542 Atlantis(线段树扫描线求矩形并的面积)
- hdu 1542 Atlantis 线段树+矩形面积并+离散化点
- hdu 1542(线段树 求矩形面积并)Atlantis
- hdu1542 Atlantis【矩形面积并+线段树】
- hdu 1542 Atlantis 线段树矩形面积并+离散化
- HDU - 1542 Atlantis(线段树扫描线求矩形面积并)
- 【HDU】1542 Atlantis 矩形面积并->线段树
- hdu 1542 Atlantis(线段树进阶,扫描线,矩形面积并)
- Hdu 1542 Atlantis 线段树 求矩形面积并
- hdu 1542 Atlantis (线段树求矩形面积并)
- HDU 1542 Atlantis (线段树求矩阵覆盖面积)
- 算法总结:【线段树+扫描线】&矩形覆盖求面积/周长问题(HDU 1542/HDU 1828)
- Hdu 1542 Atlantis 线段树 求矩形面积并
- HDU - 1255 覆盖的面积(线段树-矩形交面积)
- HDU1542 Atlantis(扫描线+矩形面积并+线段树)
- HDU-1542 Atlantis (线段树 求所有矩形面积和)
- HDU - 1255 覆盖的面积(线段树求矩形面积交 扫描线+离散化)
- HDU1542——Atlantis(扫描线,线段树,矩形面积并,离散化)
- HDU 1255 覆盖的面积 (扫描线 线段树 离散化 矩形面积并)
- HDU 1255 覆盖的面积(线段树求矩形面积交)