HDU 5033

来源:互联网 发布:mysql从excel导入数据 编辑:程序博客网 时间:2024/06/04 00:53
题意: 给你 N 楼房, 然后给你m个人站在这些楼房之间, 问看到天空的仰角是多少度

思路: 对于每一个人, 算出左边的凸包, 和右边的凸包, 找出最大斜率点, 算角度即可

(我在线算比较费时, 离线可以省时间)

#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<cmath>using namespace std;const double INF=2e9;const int maxn = 1e5 + 131;const double PI = acos(-1.0);const double eps = 1e-8;struct Point{    double x, y;    int pos;    Point(int x = 0,int y = 0): x(x), y(y) {}    //Point(){}};int dcmp(double x){    if(fabs(x) < eps) return 0;    if(x < 0) return -1;    else return 1;}typedef Point Vector;Vector operator + (Vector A, Vector B) { return Vector(A.x+B.x, A.y+B.y); }Vector operator - (Point  A, Point  B) { return Vector(A.x-B.x, A.y-B.y); }bool operator < (Point A, Point B) { return A.x < B.x; }int Cross(Vector A, Vector B) { return dcmp(A.x*B.y - A.y*B.x); }double Dot(Vector A, Vector B) { return double(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)); }Point p[maxn], ch[maxn];int PreL[maxn], PreR[maxn];void ConVexHull(Point *p, int n, Point *ch){    int m = 0;    PreL[0] = 0;    for(int i = 0; i < n; ++i) {        while(m > 1 && dcmp(Cross(ch[m-1] - ch[m-2], p[i]-ch[m-2]) > 0)) m--;        ch[m++] = p[i];        if(i) PreL[i] = ch[m-2].pos;    }    m = 0;    PreR[n-1] = n-1;    for(int i = n-1; i >= 0; --i) {        while(m > 1 && dcmp(Cross(ch[m-1] - ch[m-2], p[i]-ch[m-2]) < 0)) m--;        ch[m++] = p[i];        if(n-1-i) PreR[i] = ch[m-2].pos;    }}int lb(double xx,int n){    int left = 0, right = n;    p[n].x = INF;    while(left < right)    {        int mid=(left+right)>>1;        if(xx<p[mid].x)            right=mid;        else            left=mid+1;    }    return left-1;}int main(){    int t;    scanf("%d",&t);    for(int kase = 1; kase <= t; ++kase)    {        int n;        scanf("%d",&n);        for(int i = 0; i < n; ++i)        {            scanf("%lf%lf", &p[i].x, &p[i].y);        }        sort(p,p+n);        for(int i = 0; i < n; ++i) p[i].pos = i;        ConVexHull(p,n,ch);        /*for(int i = 0; i < n; ++i)            cout << PreL[i] << " ";            cout <<endl;        for(int i = 0; i < n; ++i)            cout << PreR[i] << " ";            cout <<endl;*/        int Q; double pos;        scanf("%d",&Q);        printf("Case #%d:\n",kase);        while(Q--)        {            scanf("%lf",&pos);            int lll = lb(pos,n);            int rrr = lll + 1;            Point New(pos, 0);            /*cout << New.x << "   " << New.y <<endl;            cout << p[lll].x << "  " << p[lll].y << endl;            cout << p[rrr].x << "  " << p[rrr].y << endl;            cout << "***********************\n";            cout << p[PreL[lll]].x << "  " << p[PreL[lll]].y <<endl;            cout << p[n-PreR[rrr]-1].x << "  " << p[n-1-PreR[rrr]].y <<endl;*/            Vector L, R;            while(dcmp(Cross(p[lll]-New, p[PreL[lll]]-New) < 0)) lll = PreL[lll];            L = p[lll]-New;            while(dcmp(Cross(p[rrr]-New, p[PreR[rrr]]-New) > 0)) rrr = PreR[rrr];            R = p[rrr] - New;            //cout << "L : \n" << L.x << "  " << L.y<< endl;            //cout << "R : \n" << R.x << "  " << R.y<< endl;            double Degree = fabs(Angle(L,R)*180 / PI);            printf("%.10f\n",Degree);        }    }}

  

0 0
原创粉丝点击