题意:
就是扫描线求面积交
解析:
参考求面积并。。。。 就是把down的判断条件改了一下。。由w > 0 改为 w > 1 同时要讨论一下 == 1 时 的情况, 所以就要用到一个临时的sum。。
具体看代码把
#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 = 2010, INF = 0x7fffffff; double X[maxn]; //记录x的坐标 struct node{ int l, r; // 线段树的左右端点 int w; // 记录边重叠的情况 double lx, rx, sum, lsum; //sum代表当前区间线段的长度,lx和rx为线段的真实端点 }Node[maxn*3]; 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 = Node[k].lsum = 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 > 1) { Node[k].sum = Node[k].lsum = Node[k].rx - Node[k].lx; return; } else if(Node[k].w == 1) { Node[k].lsum = Node[k].rx - Node[k].lx; if(Node[k].l + 1 == Node[k].r) Node[k].sum = 0; else Node[k].sum = Node[k*2].lsum + Node[k*2+1].lsum; } else { if(Node[k].l + 1 == Node[k].r) Node[k].sum = Node[k].lsum = 0; else { Node[k].sum = Node[k*2].sum + Node[k*2+1].sum; Node[k].lsum = Node[k*2].lsum + Node[k*2+1].lsum; } } } 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, T; scanf("%d",&T); while(T--) { scanf("%d",&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); int m = unique(X+1, X+cnt+1) - (X+1); build(1, 1, m); 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("%.2f ",ret); } return 0; }