离散化问题

The Sky is the Limit (World Finals 2008)

题目传送:UVALive - 4127 - The Sky is the Limit

大白书离散化简单题。。

找了半天错误,,居然是少输出一个空行。。。顿时感觉自己萌萌哒。。。

其中计算几何是套的之前留下的模板。。

AC代码:

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <complex>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <sstream>
#include <utility>
#include <iostream>
#include <algorithm>
#include <functional>
#define LL long long
#define INF 0x7fffffff
using namespace std;

struct Point {
    double x, y;
    Point(double x = 0, double y = 0) : x(x) , y(y) { }  
};

typedef Point Vector;  

Vector operator + (Vector A, Vector B) { return Vector(A.x+B.x, A.y+B.y); }
Vector operator - (Vector A, Vector B) { return Vector(A.x-B.x, A.y-B.y); }
Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); }
Vector operator / (Vector A, double p) { return Vector(A.x/p, A.y/p); } 

bool operator < (const Point& a, const Point& b) {
    return a.x < b.x || (a.x == b.x && a.y < b.y);
} 

const double eps = 1e-8;
int dcmp(double x) {
    if(fabs(x) < eps) return 0; else return x < 0 ? -1 : 1;
}

bool operator == (const Point& a, const Point& b) {
    return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
}

double Dot(Vector A, Vector B) { return A.x*B.x + A.y*B.y; } 
double Length(Vector A) { return sqrt(Dot(A, A)); }     
double Angle(Vector A, Vector B) { return acos(Dot(A, B) / Length(A) / Length(B)); } 

double Cross(Vector A, Vector B) { return A.x*B.y - A.y*B.x; }
double Area2(Point A, Point B, Point C) { return Cross(B-A, C-A); }

Vector Rotate(Vector A, double rad) {
    return Vector(A.x*cos(rad) - A.y*sin(rad), A.x*sin(rad)+A.y*cos(rad) );
} 

Vector Normal(Vector A) {  
    double L = Length(A);  
    return Vector(-A.y/L, A.x/L);  
}

Point GetLineIntersection(Point P, Vector v, Point Q, Vector w) {
    Vector u = P - Q;
    double t = Cross(w, u) / Cross(v, w);
    return P + v * t;
} 

double DistanceToLine(Point P, Point A, Point B) {  
    Vector v1 = B-A, v2 = P - A;  
    return fabs(Cross(v1,v2) / Length(v1)); 
}  

double DistanceToSegment(Point P, Point A, Point B) {  
    if(A==B) return Length(P-A);  
    Vector v1 = B - A, v2 = P - A, v3 = P - B;  
    if(dcmp(Dot(v1, v2)) < 0) return Length(v2);  
    else if(dcmp(Dot(v1, v3)) > 0) return Length(v3);  
    else return fabs(Cross(v1, v2)) / Length(v1);  
}  

Point GetLineProjection(Point P, Point A, Point B) {
    Vector v = B - A;
    return A + v * ( Dot(v, P-A) / Dot(v, v) ); 
}  

bool SegmentProperIntersection(Point a1, Point a2, Point b1, Point b2) {
    double c1 = Cross(a2 - a1, b1 - a1), c2 = Cross(a2 - a1, b2 - a1),
            c3 = Cross(b2 - b1, a1 - b1), c4 = Cross(b2 - b1, a2 - b1);
    return dcmp(c1) * dcmp(c2) < 0 && dcmp(c3) * dcmp(c4) < 0;
} 

bool OnSegment(Point p, Point a1, Point a2) {
    return dcmp(Cross(a1 - p, a2 - p)) == 0 && dcmp(Dot(a1 - p, a2 - p)) < 0;
} 

double ConvexPolygonArea(Point* p, int n) {  
    double area = 0;  
    for(int i = 1; i < n-1; i++)  
        area += Cross(p[i] - p[0], p[i + 1] - p[0]);  
    return area / 2;  
}  

double x[100005];
int n;

Point L[105][2][2];

int main() {
    int cas = 1;
    while(scanf("%d", &n) != EOF) {
        if(n == 0) break;
        memset(x, 0, sizeof(x));
        memset(L, 0, sizeof(L));
        int c = 0;
        for(int i = 0; i < n; i ++) {
            double X, H, B;
            scanf("%lf %lf %lf", &X, &H, &B);
            L[i][0][0] = Point(X - B * 0.5, 0);
            L[i][0][1] = L[i][1][0] = Point(X, H);
            L[i][1][1] = Point(X + B * 0.5, 0);
            x[c ++] = X - B * 0.5;
            x[c ++] = X;
            x[c ++] = X + B * 0.5;
        }
        for(int i = 0; i < n; i ++) 
            for(int a = 0; a < 2; a ++) {
                for(int j = i + 1; j < n; j ++) {
                    for(int b = 0; b < 2; b ++) {
                        Point P1 = L[i][a][0], P2 = L[i][a][1], P3 = L[j][b][0], P4 = L[j][b][1];
                        if(SegmentProperIntersection(P1, P2, P3, P4)) {
                            x[c ++] = GetLineIntersection(P1, P2 - P1, P3, P4 - P3).x;
                        }
                    }
                }
            }
        sort(x, x + c);
        c = unique(x, x + c) - x;

        double ans = 0;
        for(int i = 0; i < c - 1; i ++) {
            double maxy = 0, ma = 0;
            Point P3 = Point(x[i], 0);
            Point P4 = Point(x[i], 1);
            Point P5 = Point(x[i + 1], 0);
            Point P6 = Point(x[i + 1], 1);
            for(int j = 0; j < n; j ++) {
                for(int a = 0; a < 2; a ++) {
                    Point P1 = L[j][a][0], P2 = L[j][a][1];
                    if(P1.x <= x[i] && P2.x >= x[i + 1]) {
                        double y1 = GetLineIntersection(P1, P2 - P1, P3, P4 - P3).y;
                        double y2 = GetLineIntersection(P1, P2 - P1, P6, P6 - P5).y;
                        double y = (y1 + y2) / 2;
                        if(y > maxy) {
                            maxy = y;
                            ma = sqrt((y1 - y2) * (y1 - y2) + (x[i] - x[i + 1]) * (x[i] - x[i + 1]));
                        }
                    }
                }
            }
            ans += ma;
        }
        //int anss = (int)(ans + 0.5) > (int) ans ? (int) ans + 1 : (int) ans;
        printf("Case %d: %d\n\n", cas ++, (int)round(ans));
    }
    return 0;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值