hiho 1642 三角形面积和 [Offer收割]编程练习赛37 Problem B

来源:互联网 发布:东莞淘宝摄影 编辑:程序博客网 时间:2024/06/05 19:21

题目2 : 三角形面积和

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

如下图所示,在X轴上方一共有N个等腰直角三角形。这些三角形的斜边与X轴重合,斜边的对顶点坐标是(Xi, Yi)。

             (11,5)      (4,4)    /\        /\(7,3)  \       /  \/\/    \      /   /\/\     \     /   / /\ \     \------------------------->

你能求出这些三角形覆盖的面积之和吗? (重叠部分只算一次)

输入

第一行包含一个整数N。  

以下N行每行包含两个整数(Xi, Yi),代表第i个三角形顶点的坐标。

对于30%的数据,1 ≤ N ≤ 100, 0 ≤ Xi, Yi ≤ 100  

对于100%的数据,1 ≤ N ≤ 100000,0 ≤ Xi, Yi ≤ 100000

输出

覆盖的面积,保留2位小数。

样例输入
3   7 34 4  11 5
样例输出
42.00

#include <iostream>#include <stdio.h>#include <math.h>#include <stdlib.h>#include <string>#include <string.h>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <stack>#include <bits/stdc++.h>using namespace std;struct Triangle{    int top,l,r;    Triangle(){}    Triangle(int x,int y){        top=y;        l=x-y;        r=x+y;    }    friend bool operator<(const Triangle &a,const Triangle &b){        if(a.r==b.r)return a.top<b.top;        return a.r<b.r;    }};double calculate(Triangle a,Triangle b){    double r1=a.r;    double l2=b.l;    double top2=b.top;    return top2*top2-(r1-l2)*(r1-l2)*0.25;    //return ((r1-l2)*top2-(r1-l2)*(r1-l2)/2.0+2*top2*top2-top2*(r1-l2))/2.0;    //return ((r1-l2)/sqrt(2)+sqrt(2)*top2)*(sqrt(2)*top2-(r1-l2)/sqrt(2))/2.0;}Triangle A[100009];Triangle B[100009];//a list/*20 100000100000 100000*/int main(){    int N;    cin>>N;    for(int i=0;i<N;i++){        int x,y;        cin>>x>>y;        A[i]=Triangle(x,y);    }    sort(A,A+N);    B[0]=A[0];    int num=1;    for(int i=1;i<N;i++){        while(num>0&&((B[num-1].l>=A[i].l)||(B[num-1].r==A[i].r)))num--;//        B[num++]=A[i];    }    double S=(double)B[0].top*(double)B[0].top;    for(int i=1;i<num;i++){        if(B[i].l>B[i-1].r){            S+=(double)B[i].top*(double)B[i].top;            continue;        }        S+=calculate(B[i-1],B[i]);    }    printf("%.2lf\n",S);    return 0;}////                       _oo0oo_//                      o8888888o//                      88" . "88//                      (| -_- |)//                      0\  =  /0//                    ___/`---'\___//                  .' \\|     |// './/                 / \\|||  :  |||// \//                / _||||| -:- |||||- \//               |   | \\\  -  /// |   |//               | \_|  ''\---/''  |_/ |//               \  .-\__  '-'  ___/-. ///             ___'. .'  /--.--\  `. .'___//          ."" '<  `.___\_<|>_/___.' >' "".//         | | :  `- \`.;`\ _ /`;.`/ - ` : | |//         \  \ `_.   \_ __\ /__ _/   .-` /  ///     =====`-.____`.___ \_____/___.-`___.-'=====//                       `=---='//////     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~////               佛祖保佑         永无BUG//////

思路:先按照三角形的右下角的端点坐标排序,然后去掉包含的情况,从左到右加面积就行了


#include <iostream>#include <stdio.h>#include <math.h>#include <stdlib.h>#include <string>#include <string.h>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <stack>#include <bits/stdc++.h>using namespace std;struct Triangle{    int top,l,r;    Triangle(){}    Triangle(int x,int y){        top=y;        l=x-y;        r=x+y;    }    friend bool operator<(const Triangle &a,const Triangle &b){        if(a.r==b.r)return a.top<b.top;        return a.r<b.r;    }};double calculate(Triangle a,Triangle b){    double r1=a.r;    double l2=b.l;    double top2=b.top;    return top2*top2-(r1-l2)*(r1-l2)*0.25;    //return ((r1-l2)*top2-(r1-l2)*(r1-l2)/2.0+2*top2*top2-top2*(r1-l2))/2.0;    //return ((r1-l2)/sqrt(2)+sqrt(2)*top2)*(sqrt(2)*top2-(r1-l2)/sqrt(2))/2.0;}Triangle A[100009];Triangle B[100009];//a list/*20 100000100000 100000*/int main(){    int N;    cin>>N;    for(int i=0;i<N;i++){        int x,y;        cin>>x>>y;        A[i]=Triangle(x,y);    }    sort(A,A+N);    B[0]=A[0];    int num=1;    for(int i=1;i<N;i++){        while(num>0&&((B[num-1].l>=A[i].l)||(B[num-1].r==A[i].r)))num--;//        B[num++]=A[i];    }    double S=(double)B[0].top*(double)B[0].top;    for(int i=1;i<num;i++){        if(B[i].l>B[i-1].r){            S+=(double)B[i].top*(double)B[i].top;            continue;        }        S+=calculate(B[i-1],B[i]);    }    printf("%.2lf\n",S);    return 0;}////                       _oo0oo_//                      o8888888o//                      88" . "88//                      (| -_- |)//                      0\  =  /0//                    ___/`---'\___//                  .' \\|     |// './/                 / \\|||  :  |||// \//                / _||||| -:- |||||- \//               |   | \\\  -  /// |   |//               | \_|  ''\---/''  |_/ |//               \  .-\__  '-'  ___/-. ///             ___'. .'  /--.--\  `. .'___//          ."" '<  `.___\_<|>_/___.' >' "".//         | | :  `- \`.;`\ _ /`;.`/ - ` : | |//         \  \ `_.   \_ __\ /__ _/   .-` /  ///     =====`-.____`.___ \_____/___.-`___.-'=====//                       `=---='//////     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~////               佛祖保佑         永无BUG//////




阅读全文
1 0