Lightoj 1203

来源:互联网 发布:网络伤感歌曲打包下载 编辑:程序博客网 时间:2024/05/01 04:34

题目链接: 点这里
题意:给n个点,求从某一点看到所有点的角度,使这个角度最小。
思路:先求出凸包,然后在枚举凸包上的每个点看到所有点的角度大小。
WA了几次(有重复的点),

AC代码:

#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#include <stack>#include <queue>#include <vector>#include <cmath>#include <map>#include <set>#define ll long long#define llu unsigned long longusing namespace std;const int maxn = 100010;const double eps = 1e-10;const double PI  = acos(-1.0);struct Point {    double x,y;    Point (double x = 0,double y = 0) : x(x),y(y) {}};Point p[100050],s[100500],ans[100050];struct Line{    Point a,b;};Line line[100];int indl,indp;bool dcmp(double x) {    if(fabs(x)-0.0 <= eps) return true;    return false;}int n;double dis(Point a,Point b) {    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}double cross(Point a,Point b,Point c) {    if(dcmp((b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y))) return 0;    return ((b.x-a.x)*(c.y-a.y) - (c.x-a.x)*(b.y-a.y));}bool cmp1(Point a,Point b) {    if(!dcmp(a.x-b.x)) return a.x<b.x;    else return a.y<b.y;}bool cmp2(Point a,Point b) {    double m = cross(p[1],a,b);    if(dcmp(m)) {        return dis(b,p[1]) > dis(a,p[1]);    }else {        if(m>0) return true;        else return false;    }}double Dot(Point a,Point b,Point c) {    return (b.x-a.x)*(c.x-a.x)+(b.y-a.y)*(c.y-a.y);}double angle(Point a,Point b,Point c) {    return acos(Dot(a,b,c)/(dis(a,b)*dis(a,c)));}Point A;int main(){    int T; scanf("%d",&T);    for(int cas = 1; cas<=T; cas++){        scanf("%d",&n);        for(int i=1;i<=n;i++) {            scanf("%lf%lf",&p[i].x,&p[i].y);        }        if(n<=2) {            printf("Case %d: 0.00000000\n",cas); continue;        }        sort(p+1,p+n+1,cmp1);        sort(p+2,p+n+1,cmp2);        s[1] = p[1];        s[2] = p[2];        int top = 2;        for(int i=3;i<=n; i++) {            while(top>=2 && cross(s[top-1],s[top],p[i]) <= 0 ) top--;            s[++top] = p[i];        }        int id = 1;        A.x = s[1].x; A.y = s[1].y;        ans[id] = A;        for(int i=2;i<=top;i++) {            if(dcmp(s[i].x-A.x)&&dcmp(s[i].y-A.y)) {                continue;            }else {                A.x = s[i].x; A.y = s[i].y;                ans[++id] = A;            }        }        if(id <= 2) {            printf("Case %d: 0.00000000\n",cas); continue;        }        ans[0]=ans[id];        ans[++id]=ans[1];        double Min = 800;        for(int i=1;i<id; i++) {            Min = min(Min,angle(ans[i],ans[i-1],ans[i+1]));        }        printf("Case %d: %.10lf\n",cas,Min*180/PI);    }    return 0;}/*150 00 00 00 00 00.000000*/
0 0
原创粉丝点击