• [2019HDU多校第三场][HDU 6603][A. Azshara's deep sea]


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6603

    题目大意:给出一个凸包,凸包内有若干个圆,要求画尽可能多的对角线使得他们两两不在凸包内相交且不与任意一个圆有公共点

    题解:先预处理出所有点对间的连线是否会和圆有公共点,记为x[i][j],之后进行区间DP。设f[i][d]表示从第(i)个点到(i+d)个点这个区间之内最多能画多少条对角线,那么就有(f[i][d]=x[i][nxt]+max(f[i][d-1],f[i+1][d-1])),答案取f[i][d]的最大值即可

       复杂度分析:求凸包(O(nlogn)),预处理(O(n^2g)),DP(O(n^2)),总时间复杂度为(O(n^2g))

    吐槽:本题题面又臭又长,严重影响观看体验

       给出的(n)个点不一定是凸包的顶点,所以要先求一次凸包,而且这么重要的条件居然是隐藏在巨大题面的一个小括号里的,坑了不少人

       最后3分钟才发现这个隐藏条件,赶紧拉了个模板出来最后各种调参数终于在最后一分钟爆过去了orz...

    #include<bits/stdc++.h>
    using namespace std;
    #define N 401
    #define LL long long
    const double eps=1e-9;
    int sgn(double x)
    {
        if (x<-eps) return -1;
        if (x>eps) return 1;
        return 0;
    }
    struct Point
    {
        double x,y;
        void read(){scanf("%lf%lf",&x,&y);}
        Point operator -(const Point &t)const{return {x-t.x,y-t.y};}
        double operator *(const Point &t)const{return x*t.y-y*t.x;}
        double length()const{return sqrt(x*x+y*y);}
        double ang()const
        {
            return atan2(1.0*y,1.0*x);
        }
    }b[N];
    Point cent;
    bool cmpang(const Point &p1,const Point &p2)
    {
        int tmp=sgn( (p1-cent).ang() - (p2-cent).ang() );
        if (tmp!=0) return tmp<0;
        return (p1-cent).length() < (p2-cent).length();
    }
    struct POLYGON
    {
        int n;
        Point a[N];
        void ChangetoConvex()
        {
            for (int i=2;i<=n;i++)
                if (a[i].x<a[1].x||a[i].x==a[1].x&&a[i].y<a[1].y)
                    swap(a[1],a[i]);
            cent=a[1];
            sort(a+2,a+n+1,cmpang);
            int top=2;
            for (int i=3;i<=n;i++)
            {
                while(top>=2&&
                    (a[top]-a[top-1])*(a[i]-a[top])<=0 )
                        top--;
                a[++top]=a[i];
            }
            n=top;
        }
    }P;
    int T,n,g,r,x[N][N],f[N][N];
    bool check(int x,int y)
    {
        if(x%n+1==y || y%n+1==x)
          return false;
        double dis=(P.a[x]-P.a[y]).length();
        for(int i=1;i<=g;i++)
          {
          double cha=abs((P.a[y]-P.a[x])*(b[i]-P.a[x]));
          if(cha+eps<=1.0*r*dis)return false;
          }
        return true;
    }
    void init()
    {
        int ans=0;
        memset(f,0,sizeof(f));
        scanf("%d%d%d",&n,&g,&r);
        P.n=n;
        for(int i=1;i<=n;i++)
          P.a[i].read();
        for(int i=1;i<=g;i++)
          b[i].read();
        P.ChangetoConvex();
        n=P.n;
        for(int i=1;i<=n;i++)
          for(int j=i+1;j<=n;j++)
            x[i][j]=x[j][i]=check(i,j);
        for(int d=2;d<=n-2;d++)
          for(int i=1;i<=n;i++)
            {
            int nxt=(i+d-1)%n+1,res=0;
            res=max(f[i][d-1],f[i%n+1][d-1]);
            f[i][d]=x[i][nxt]+res;
            ans=max(ans,f[i][d]);
            }
        printf("%d
    ",ans);
    }
    int main()
    {
        scanf("%d",&T);
        while(T--)init();
    }
    View Code
  • 相关阅读:
    机器重装后几个要记的问题
    JS中split用法和数组中元素的删除
    免费软件的盈利方式
    web程序的发布及相关问题
    无法直接启动带有“类库输出类型”的项目
    System.Data.OracleClient 需要 Oracle 客户端软件 8.1.7 或更高版本
    orcale不同版本数据导入、导出及库版本查询
    VSc# web程序:gridview保存Excel文件遇到的问题
    油田生产中的几个“三”
    web跨页面传值——FORM表单(c#)
  • 原文地址:https://www.cnblogs.com/DeaphetS/p/11265399.html
Copyright © 2020-2023  润新知