Picture POJ - 1177(扫描线求面积并)
题意:求矩形并的面积。。
解析:
扫描线第一道题。。。。自下而上扫描的。。。
如果不懂什么是扫描线 戳我
#include <iostream> #include <cstdio> #include <sstream> #include <cstring> #include <map> #include <set> #include <vector> #include <stack> #include <queue> #include <algorithm> #include <cmath> #define MOD 2018 #define LL long long #define ULL unsigned long long #define Pair pair<int, int> #define mem(a, b) memset(a, b, sizeof(a)) #define _ ios_base::sync_wity_stdio(0),cin.tie(0) //freopen("1.txt", "r", stdin); using namespace std; const int maxn = 201, INF = 0x7fffffff; double X[maxn]; //记录x的坐标 struct node{ int l, r; // 线段树的左右端点 int w; // 记录边重叠的情况 double lx, rx, sum; //sum代表当前区间线段的长度,lx和rx为线段的真实端点 }Node[maxn*4]; struct edge{ double lxx, rxx, y; // 存储边的左右端点和y int f; //标记是下边还是上边 (下边为1 上边为-1) }Edge[maxn]; int cmp(edge a, edge b) { return a.y < b.y; // 按y从小到大排序 把线段的高度从低到高排序 } void build(int k, int ll, int rr) //建树 { Node[k].l = ll, Node[k].r = rr; Node[k].sum = Node[k].w = 0; Node[k].lx = X[ll]; Node[k].rx = X[rr]; if(ll + 1 == rr) return; int m = (ll + rr) / 2; build(k*2, ll, m); build(k*2+1, m, rr); } void down(int k) //计算长度 { if(Node[k].w > 0) { Node[k].sum = Node[k].rx - Node[k].lx; return; } if(Node[k].l + 1 == Node[k].r) Node[k].sum = 0; else { Node[k].sum = Node[k*2].sum + Node[k*2+1].sum; } } void update(int k, edge e) // 更新 { if(Node[k].lx == e.lxx && Node[k].rx == e.rxx) { Node[k].w += e.f; down(k); return; } if(e.rxx <= Node[k*2].rx) update(k*2, e); else if(e.lxx >= Node[k*2+1].lx) update(k*2+1, e); else { edge g = e; g.rxx = Node[k*2].rx; update(k*2, g); g = e; g.lxx = Node[k*2+1].lx; update(k*2+1, g); } down(k); } int main() { int n, cnt, kase = 0; while(~scanf("%d",&n) && n) { cnt = 0; for(int i=0; i<n; i++) { double x1, y1, x2, y2; scanf("%lf%lf%lf%lf",&x1, &y1, &x2, &y2); Edge[++cnt].lxx = x1, Edge[cnt].rxx = x2, Edge[cnt].y = y1, Edge[cnt].f = 1; X[cnt] = x1; Edge[++cnt].lxx = x1, Edge[cnt].rxx = x2, Edge[cnt].y = y2, Edge[cnt].f = -1; X[cnt] = x2; } sort(Edge+1, Edge+cnt+1, cmp); sort(X+1, X+cnt+1); build(1, 1, cnt); double ret = 0; for(int i=1; i<cnt; i++) { update(1, Edge[i]); ret += (Edge[i+1].y - Edge[i].y) * Node[1].sum; } printf("Test case #%d\nTotal explored area: %.2f\n\n",++kase,ret); } return 0; }
自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 数据库服务器 SQL Server 版本升级公告
· 程序员常用高效实用工具推荐,办公效率提升利器!
· C#/.NET/.NET Core技术前沿周刊 | 第 23 期(2025年1.20-1.26)