• Bzoj2829 信用卡凸包


    Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special Judge
    Submit: 333  Solved: 155

    Description

    Input

    Output

    Sample Input

    2
    6.0 2.0 0.0
    0.0 0.0 0.0
    2.0 -2.0 1.5707963268

    Sample Output

    21.66

    HINT


    本样例中的2张信用卡的轮廓在上图中用实线标出,如果视1.5707963268为

    Pi/2(pi为圆周率),则其凸包的周长为16+4*sqrt(2)

    Source

    几何 凸包

    把矩形边长减去圆的直径,得到有效边长。计算出每个矩形的四个点,找到凸包,再加上一个圆的周长就是答案。

    迷之WA,注释掉的旋转方法不知为何不对(小样例居然都过了)

     1 /*by SilverN*/
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 #include<vector>
     8 using namespace std;
     9 const double Pi=acos(-1.0);
    10 const int mxn=100010;
    11 struct point{
    12     double x,y;
    13     point operator - (point rhs){return (point){x-rhs.x,y-rhs.y};}
    14     point operator + (point rhs){return (point){x+rhs.x,y+rhs.y};}
    15 }p[mxn];
    16  
    17 double cross(point a,point b){return a.x*b.y-a.y*b.x;}
    18 double dist(point a,point b){return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}
    19 int cmp(point a,point b){
    20     double tmp=cross(a-p[1],b-p[1]);
    21     return (tmp<0 || (tmp==0 && dist(a,p[0])>dist(b,p[0])));
    22 }
    23 int cmp2(point a,point b,point p){
    24     double tmp=cross(a-p,b-p);
    25     return (tmp<0 || (tmp==0 && dist(a,p)>=dist(b,p)));
    26 }
    27 point rotate(point a,double angle){
    28     return (point){a.x*cos(angle)-a.y*sin(angle),a.x*sin(angle)+a.y*cos(angle)};
    29 }
    30 point move(point a,double len,double an){
    31     return (point){a.x+len*cos(an),a.y+len*sin(an)};
    32 }
    33 int n;
    34 double a,b,r;
    35 double x,y,th;
    36 int st[mxn],top;
    37 int main(){
    38     int i,j;
    39     scanf("%d",&n);
    40     scanf("%lf%lf%lf",&a,&b,&r);
    41     a-=2*r;b-=2*r;
    42     top=0;
    43     for(i=1;i<=n;i++){
    44         scanf("%lf%lf%lf",&x,&y,&th);
    45         for(j=1;j<=4;j++)
    46         {
    47             point tmp=move((point){x,y},b/2,th+Pi*(j-1)/2);
    48             p[++top]=move(tmp,a/2,th+Pi*j/2);
    49             swap(a,b);
    50         }        
    51 //        point tmp;
    52 /*
    53         tmp.x=a/2;tmp.y=b/2;p[++top]=(point){x,y}+rotate(tmp,th);
    54         tmp.x=-a/2;tmp.y=b/2;p[++top]=(point){x,y}+rotate(tmp,th);
    55         tmp.x=a/2;tmp.y=-b/2;p[++top]=(point){x,y}+rotate(tmp,th);
    56         tmp.x=-a/2;tmp.y=-b/2;p[++top]=(point){x,y}+rotate(tmp,th);
    57 */
    58     }
    59     n=top;top=0;
    60     int s=1;
    61     for(i=1;i<=n;i++){
    62         if(p[i].x<p[s].x || (p[i].x==p[s].x && p[i].y<p[s].y))s=i;
    63     }
    64     swap(p[s],p[1]);
    65     sort(p+2,p+n+1,cmp);
    66     p[n+1]=p[1];
    67     n++;
    68     for(i=1;i<=n;i++){
    69         while(top>1 && cmp2(p[i],p[st[top]],p[st[top-1]]))top--;
    70         st[++top]=i;
    71     }
    72     double ans=0;
    73     ans+=Pi*2*r;
    74     for(i=1;i<top;i++){
    75         ans+=sqrt(dist(p[st[i]],p[st[i+1]]));
    76     }
    77     printf("%.2lf
    ",ans);
    78     return 0;
    79 }
    80 /*
    81 5
    82 12.0 6.0 2.0
    83 0.0 0.0 0.0
    84 1 1 1
    85 2 2 1.5707963268
    86 1 7 0
    87 2.0 -2.0 1.5707963268
    88 */
    本文为博主原创文章,转载请注明出处。
  • 相关阅读:
    Java1.7的HashMap源码分析-面试必备技能
    Springboot集成Swagger2
    springsecurity简单学习
    Java8的新特性
    HttpClient
    Filter的使用
    Spring拦截器和SpringAop实现
    运维工程师打怪升级进阶之路 V2.0
    欢迎加入微信交流群交流
    赞!7000 字学习笔记,一天搞定 MySQL
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6495699.html
Copyright © 2020-2023  润新知