对应HDU题目:点击打开链接
Time Limit: 1000MS | Memory Limit: 32768KB | 64bit IO Format: %I64d & %I64u |
Description
Input
Output
Sample Input
2 10 10 20 20 15 15 25 25.5 0
Sample Output
Test case #1 Total explored area: 180.00
Source
题意:矩阵面积并
思路:线段树扫描线,从左往右扫或从下往上扫,含浮点数,故要离散化
#include<cstdio> #include<cstdlib> #include<cmath> #include<map> #include<queue> #include<stack> #include<vector> #include<algorithm> #include<cstring> #include<string> #include<iostream> const int MAXN=2000+10; #define ms(x,y) memset(x,y,sizeof(x)) using namespace std; double x[MAXN]; double sum[MAXN<<2]; int cnt[MAXN<<2]; struct Line { double y,x1,x2; int flag; }line_y[MAXN]; bool cmp(Line l1, Line l2) { return l1.y < l2.y; } void up(int rt, int left, int right) { if(cnt[rt]) sum[rt] = x[right+1] - x[left]; else if(left == right) sum[rt] = 0; else sum[rt] = sum[rt<<1] + sum[rt<<1|1]; } void update(int rt, int left, int right, int l, int r, int flag) { if(l == left && right == r){ cnt[rt]+=flag; up(rt, left, right); return; } int mid=(left + right)>>1; if(mid >= r) update(rt<<1, left, mid, l, r, flag); else if(mid < l) update(rt<<1|1, mid+1, right, l, r, flag); else{ update(rt<<1, left, mid, l, mid, flag); update(rt<<1|1, mid+1, right, mid+1, r, flag); } up(rt, left, right); } int binary(double key, int n, double *a) { int l=0, r=n-1; while(l<=r) { int mid=(l+r)>>1; if(a[mid] == key) return mid; if(a[mid] > key) r = mid - 1; else l = mid + 1; } return -1; } int main() { //freopen("in.txt","r",stdin); int n,w=0; while(scanf("%d", &n), n) { ms(x,0); ms(cnt,0); ms(sum,0); printf("Test case #%d\n", ++w); int u=0; int n_x=0; for(int i=0; i<n; i++){ double x1,y1,x2,y2; scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2); x[n_x++]=x1; x[n_x++]=x2; line_y[u].y=y1; line_y[u].flag=1; line_y[u].x1=x1; line_y[u++].x2=x2; line_y[u].y=y2; line_y[u].flag=-1; line_y[u].x1=x1; line_y[u++].x2=x2; } sort(x, x+n_x);//横坐标离散化 sort(line_y, line_y+u, cmp);//扫描线排序 int k=1; for(int i=1; i<n_x; i++) if(x[i] != x[i-1]) x[k++] = x[i]; double ans=0.0; for(int i=0; i<u-1; i++){ int l=binary(line_y[i].x1, k, x); int r=binary(line_y[i].x2, k, x); update(1, 0, k-2, l, r-1, line_y[i].flag); ans+= sum[1]*(line_y[i+1].y - line_y[i].y); } printf("Total explored area: %.2lf\n\n", ans); } return 0; }