基础练习 矩形面积交
时间限制:1.0s 内存限制:512.0MB
问题描述
平面上有两个矩形,它们的边平行于直角坐标系的X轴或Y轴。对于每个矩形,我们给出它的一对相对顶点的坐标,请你编程算出两个矩形的交的面积。
输入格式
输入仅包含两行,每行描述一个矩形。
在每行中,给出矩形的一对相对顶点的坐标,每个点的坐标都用两个绝对值不超过10^7的实数表示。
在每行中,给出矩形的一对相对顶点的坐标,每个点的坐标都用两个绝对值不超过10^7的实数表示。
输出格式
输出仅包含一个实数,为交的面积,保留到小数后两位。
样例输入
1 1 3 3
2 2 4 4
2 2 4 4
样例输出
1.00
hint:给你两个矩形的两个对角坐标,让你求面积并,这个题目的话---因为只有两个矩形,所以问题好像简单了很多呢。先判断两个矩形是否相交,不相交的话直接是0;相交的话:如果两个矩形相交,那么它们的相交面积就是所有横坐标中的中间两个横坐标之差与中间两个纵坐标之差的乘积!
从这个问题发现了自己好像线段树扫描线求矩形面积并还不会啊!!! 学习学习!!1
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 using namespace std; 6 #define lsn l, mid, rt << 1 7 #define rsn mid + 1, r, rt << 1 | 1 8 9 //因为只有两个矩形,所以可以不一定要用扫描线线段树的方法 10 //这个简单的方法到时候可以再实现 11 /* 12 typedef double db; 13 struct Scan{ 14 double l, r, h; int d; 15 Scan(){} 16 Scan(double l, double r, double h, int d) : l(l), r(r), h(h), d(d){} 17 bool operator < (const Scan & a){ 18 return this->h < a.h; //updata 19 } 20 }scan[100]; //updata 21 double sum[100]; 22 double dot[100]; 23 int cnt[100]; 24 25 void push_up(int l, int r, int rt){ 26 if(cnt[rt]) sum[rt] = dot[r + 1] - dot[l]; //updata 27 else if(l == r) sum[rt] = 0; 28 else sum[rt] = sum[rt << 1] + sum[rt << 1 | 1]; 29 } 30 void update(int L, int R, int v, int l, int r, int rt){ 31 if(L <= l && R >= r){ 32 cnt[rt] += v; 33 push_up(l, r, rt); //updata 34 return; 35 } 36 int mid = (l + r) >> 1; 37 if(L <= mid) update(L, R, v, lsn); 38 if(R > mid) update(L, R, v, rsn); 39 push_up(l, r, rt); 40 } 41 42 int main(){ 43 int cnt1=0, cnt2 = 0; 44 double ans = 0; 45 for(int i = 1; i < 3; i++){ 46 double x1, y1, x2, y2; 47 cin >> x1 >> y1 >> x2 >> y2; 48 ans += (x2 - x1) * (y2 - y1); 49 scan[++cnt1] = Scan(x1, x2, y1, 1); 50 scan[++cnt1] = Scan(x1, x2, y2, -1); 51 dot[++cnt2] = x1; dot[++cnt2] = x2; 52 } 53 sort(scan + 1, scan + 1 + cnt1); 54 sort(dot + 1, dot + 1 + cnt2); 55 int m = 1; 56 for(int i = 2; i <= cnt2; i++){ 57 if(dot[i] != dot[i - 1]) dot[++m] = dot[i]; 58 } 59 double Ans = 0; 60 //for(int i=1; i<=cnt1; i++) cout << scan[i].h << " "; 61 //cout <<endl; 62 for(int i = 1; i < cnt1; i++){ 63 int l = lower_bound(dot + 1, dot + 1 + m, scan[i].l) - dot; 64 int r = lower_bound(dot + 1, dot + 1 + m, scan[i].r) - dot; 65 //cout << l << " " << r << endl; 66 if(l < r) update(l, r - 1, scan[i].d, 1, m, 1); 67 //updata 68 Ans += sum[1] * (scan[i + 1].h - scan[i].h); 69 //cout << Ans << " " << sum[1] << " " << i << " " << scan[i+1].h << " " << scan[i].h << " " << scan[i + 1].h - scan[i].h << endl; 70 } 71 //cout << ans << " " << Ans << endl; 72 printf("%.2f\n", ans - Ans); 73 return 0; 74 } 75 */ 76 //这里有个坑。。。输入并不一定是先输入矩形的左下角再输入矩形的右下角,所以在判断是否有交之前我们要先sort一下,将左下角的坐标放在前面的位置 77 //不得不服别人的智商。。。很巧妙啊 78 double x[4], y[4]; 79 int main(){ 80 for(int i = 0; i < 4; i += 2){ 81 cin >> x[i] >> y[i] >> x[i+1] >> y[i+ 1]; 82 } 83 sort(x, x+2); 84 sort(x+2, x+4); 85 sort(y, y+2); 86 sort(y+2, y+4); 87 if(x[0] >= x[3] || x[1] <= x[2] || y[0] >= y[3] || y[1] <= y[2]){ 88 printf("0.00\n"); 89 }else{ 90 sort(x, x+4); 91 sort(y, y+4); 92 printf("%.2lf\n", (x[2] - x[1]) * (y[2] - y[1]) ); 93 } 94 return 0; 95 }