HOJ1119/HDU1542 Atlantis HOJ1909/POJ1177 Picture
来源:互联网 发布:宝塔linux面板 编辑:程序博客网 时间:2024/06/05 16:42
第一题:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542
题意:求多个长方形在平面上所覆盖的面积和。
扫描线。从下往上扫描,浮点数离散化处理。
思路参考:http://www.cnblogs.com/scau20110726/archive/2013/03/21/2972808.html
#include <iostream>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;#define Maxn 250#define lx (x<<1)#define rx ((x<<1)|1)#define MID ((l + r)>>1)double X[Maxn];double S[Maxn<<2];int cnt[Maxn<<2];struct Seg{ double l; double r; double h; int s; Seg(){} Seg(double _l,double _r,double _h,int _s) { l = _l;r = _r;h = _h;s = _s; } bool operator <(const Seg & a) const { return h<a.h; }};Seg seg[Maxn];int binarySearch(int l,int r,double x){ while(l<=r) { int mid = (l + r)>>1; if(X[mid] == x) return mid; if(X[mid]< x) l = mid+1; else r = mid-1; } return 0;}void pushUp(int l,int r,int x){ if(cnt[x]) S[x] = X[r+1] - X[l]; else if(l == r) S[x] = 0; else S[x] = S[lx] + S[rx];}void update(int L,int R,int d,int l,int r,int x){ if(L<=l && r<=R) { cnt[x] += d; pushUp(l,r,x); return; } if(L<=MID) update(L,R,d,l,MID,lx); if(MID+1<=R) update(L,R,d,MID+1,r,rx); pushUp(l,r,x);}void init(){ memset(S,0,sizeof(S)); memset(cnt,0,sizeof(cnt));}int main(){ #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif int cas = 0; int n; double a,b,c,d; int p = 0; while(scanf(" %d",&n)!=EOF && n!=0) { init(); cas++; p = 0; for(int i=0;i<n;i++) { scanf(" %lf %lf %lf %lf",&a,&b,&c,&d); X[p] = a; seg[p++] = Seg(a,c,b,1); X[p] = c; seg[p++] = Seg(a,c,d,-1); } sort(X,X+p); sort(seg,seg+p); int k = 1; //去重 for(int i=1;i<p;i++) { if(X[i]!=X[i-1]) X[k++] = X[i]; } //从下往上扫描,忽略最上部边 double ans = 0; for(int i=0;i<p-1;i++) { int l = binarySearch(0,k-1,seg[i].l); int r = binarySearch(0,k-1,seg[i].r) - 1; update(l,r,seg[i].s,0,k-1,1); ans += S[1] * (seg[i+1].h - seg[i].h); } printf("Test case #%d\nTotal explored area: %.2lf\n\n",cas,ans); } return 0;}
第二题:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1828
题意:求在平面内的长方形所形成的轮廓的周长。
思路和求面积相似。扫描线从下网上扫描,分为横边长度的记录len[]和竖边个数的记录numSeg[].分别将竖边长度和横边长度的改变绝对值都求出相加即可。
另外要考虑到竖边会重叠。使用lbd[]和rbd[]比对一下是否会重叠。
#include <iostream>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;#define Maxn 15005#define lx (x<<1)#define rx ((x<<1)|1)#define MID ((l + r)>>1)int cnt[Maxn<<2];//在横轴投影的有效长度int len[Maxn<<2];//在横轴投影的有效线段个数×2,即竖边的个数int numSeg[Maxn<<2];//区间左边界是否有竖边bool lbd[Maxn<<2];//区间右边界是否有竖边bool rbd[Maxn<<2];struct Seg{ int l,r,h,s; Seg(){} Seg(int _l,int _r,int _h,int _s) { l = _l;r = _r;h = _h;s = _s; } bool operator <(const Seg &a) const { return h<a.h || (h == a.h && s>a.s); }};Seg seg[Maxn];void pushUp(int l,int r,int x){ if(cnt[x]) { len[x] = (r - l + 1); numSeg[x] = 2; lbd[x] = rbd[x] = 1; } else if(l == r) { len[x] = numSeg[x] = lbd[x] = rbd[x] = 0; } else { lbd[x] = lbd[lx]; rbd[x] = rbd[rx]; len[x] = len[lx] + len[rx]; numSeg[x] = numSeg[lx] + numSeg[rx]; if(lbd[rx] && rbd[lx]) numSeg[x] -= 2; }}void update(int L,int R,int d,int l,int r,int x){ if(L<=l && r<=R) { cnt[x]+= d; pushUp(l,r,x); return; } if(L<=MID) update(L,R,d,l,MID,lx); if(MID+1<=R) update(L,R,d,MID+1,r,rx); pushUp(l,r,x);}void init(){ memset(cnt,0,sizeof(cnt)); memset(numSeg,0,sizeof(numSeg)); memset(len,0,sizeof(len)); memset(lbd,0,sizeof(lbd)); memset(rbd,0,sizeof(rbd));}int main(){ #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif int n; int a,b,c,d; int p,last = 0; while(scanf(" %d",&n)!=EOF) { init(); p = 0; last = 0; int leftMin = 10005,rightMax = -10005; for(int i=0;i<n;i++) { scanf(" %d %d %d %d",&a,&b,&c,&d); if(a<leftMin) leftMin = a; if(c>rightMax) rightMax = c; seg[p++] = Seg(a,c,b,1); seg[p++] = Seg(a,c,d,-1); } sort(seg,seg+p); int ans = 0; for(int i=0;i<p;i++) { update(seg[i].l,seg[i].r-1,seg[i].s,leftMin,rightMax-1,1); //为什么要取绝对值,想一下 //横边长度 ans += abs(len[1] - last); last = len[1]; //竖边长度 ans += numSeg[1]*(seg[i+1].h-seg[i].h); } printf("%d\n",ans); } return 0;}
- HOJ1119/HDU1542 Atlantis HOJ1909/POJ1177 Picture
- hdu1542 Atlantis
- HDU1542--Atlantis
- [HDU1542]Atlantis
- hdu1542----Atlantis
- hdu1542 Atlantis
- hdu1542 Atlantis
- POJ1177-Picture
- POJ1177----Picture
- poj1177 Picture
- Picture poj1177
- hdu1542 Atlantis 面积交
- HDU1542 Atlantis(面积并)
- 线段树 hdu1542 Atlantis
- HDU1542 Atlantis (扫描线)
- hdu1542 Atlantis--扫描线
- HDU1542&&POJ1151-Atlantis
- [题解]hdu1542 Atlantis
- SD 分区作为跟文件系统 启动Linux
- IOS之第一个IOS程序
- Java学习之道:[续]Spring学习笔记 -- 资源访问(Resource接口)
- hdu 4500 小Q系列故事――�丝的逆袭(检索)
- c++虚函数的学习
- HOJ1119/HDU1542 Atlantis HOJ1909/POJ1177 Picture
- 关于mysql处理百万级以上的数据时如何提高其查询速度的方法
- 找出字符串中第一个只出现过一次的字符和位置
- mysql开发报错
- FAT文件系统学习
- django输出 hello world
- JSP+Servlet的简单示例
- Java学习之道:纯Hibernate使用-不用spring事务管理
- 你所不知道的scanf ()