• Guard Duty (hard) Codeforces


    https://codeforces.com/contest/958/problem/E3

    当没有三点共线时,任意一个这样的点集都是保证可以找到答案的,(考虑任意一种有相交的连线方案,一定可以将其中两条相交的连线改成不相交的,并使得连线的总长度变小;显然连线的总长度最小的方案一定存在,则这种方案一定没有连线相交)

    因此可以有一个分治做法:先在当前点集中找出最左、最下的点,找出一个点与其配对,使得以这两点间连线所在的直线划分开点集后,两边各自都满足白点数等于黑点数;显然一定能找到这个与其配对的点

    找的方法就是其他点以选出这个点为中心做极角排序,然后双指针

    复杂度n^2*log

    本来以为分治时可以随便找出一个点,但事实上这样不对的,举个例子:

    (以A2为选出点,则找不到配对点)

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<vector>
      5 #include<cmath>
      6 using namespace std;
      7 #define fi first
      8 #define se second
      9 #define mp make_pair
     10 #define pb push_back
     11 typedef long long ll;
     12 typedef unsigned long long ull;
     13 typedef pair<int,int> pii;
     14 namespace X
     15 {
     16     struct Point
     17     {
     18         int x,y;
     19         Point(int x=0,int y=0):x(x),y(y){}
     20     };
     21     typedef Point Vec;
     22     Vec operator+(const Vec& a,const Vec& b)
     23     {
     24         return Vec(a.x+b.x,a.y+b.y);
     25     }
     26     Vec operator-(const Vec& a,const Vec& b)
     27     {
     28         return Vec(a.x-b.x,a.y-b.y);
     29     }
     30     int dcmp(int x)
     31     //正为1,负为-1,0为0
     32     {
     33         if(x==0)    return 0;
     34         return x<0?-1:1;
     35     }
     36     bool operator==(const Vec& a,const Vec& b)
     37     //判向量相等
     38     {
     39         return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
     40     }
     41     double cross(const Vec& a,const Vec& b)
     42     //叉积
     43     {
     44         return a.x*b.y-a.y*b.x;
     45     }
     46 };
     47 using namespace X;
     48 Point p[20100];
     49 int an[10100];
     50 int d[20100],tmp[20100];
     51 int n;
     52 double ang[20100];
     53 bool vis[20100];
     54 bool c1(int a,int b)
     55 {
     56     return ang[a]<ang[b];
     57 }
     58 bool c2(int a,int b)
     59 {
     60     return p[a].x<p[b].x||(p[a].x==p[b].x&&p[a].y<p[b].y);
     61 }
     62 void solve(int l,int r)
     63 {
     64     if(r<l)    return;
     65     swap(*min_element(d+l,d+r+1,c2),d[l]);
     66     int i;
     67     for(i=l+1;i<=r;i++)
     68         ang[d[i]]=atan2(p[d[i]].y-p[d[l]].y,p[d[i]].x-p[d[l]].x);
     69     sort(d+l+1,d+r+1,c1);
     70     int len=r-l,a[]={0,0},nl,nr;
     71     for(nl=l+1,nr=l;nl<=r;nl++)//包含(nl,nr]的点,nl自身与l相连
     72     {
     73         while(nr<nl||(nr-nl+1<len&&cross(p[d[(nr-l)%len+l+1]]-p[d[l]],p[d[nl]]-p[d[l]])<0))
     74         {
     75             ++nr;
     76             a[d[(nr-l-1)%len+l+1]<=n]++;
     77         }
     78         a[d[nl]<=n]--;
     79         if(int(d[nl]<=n)+(d[l]<=n)==1&&a[0]==a[1])    break;
     80     }
     81     if(d[l]<=n)    an[d[l]]=d[nl];
     82     else    an[d[nl]]=d[l];
     83     for(i=l+1;i<=r;i++)
     84         vis[i]=0;
     85     vis[nl]=1;
     86     tmp[0]=0;
     87     for(i=nl+1;i<=nr;i++)
     88     {
     89         vis[(i-l-1)%len+l+1]=1;
     90         tmp[++tmp[0]]=d[(i-l-1)%len+l+1];
     91     }
     92     int t1=l;
     93     for(i=l+1;i<=r;i++)
     94         if(!vis[i])
     95         {
     96             d[++t1]=d[i];
     97         }
     98     int t2=t1;
     99     for(i=1;i<=tmp[0];i++)
    100         d[++t2]=tmp[i];
    101     solve(l+1,t1);solve(t1+1,t2);
    102 }
    103 int main()
    104 {
    105     int i;
    106     while(scanf("%d",&n)==1)
    107     {
    108     for(i=1;i<=2*n;i++)    scanf("%d%d",&p[i].x,&p[i].y);
    109     for(i=1;i<=2*n;i++)    d[i]=i;
    110     solve(1,2*n);
    111     for(i=1;i<=n;i++)    printf("%d
    ",an[i]-n);
    112     }
    113     return 0;
    114 }
    View Code

    双倍经验:https://vjudge.net/problem/UVA-1411

  • 相关阅读:
    bootstrap之CDN
    bootstrap之HTML模板
    Glyphicon 字体图标
    crawler4j 学习(二)
    【软件构造】第二章 软件构建的过程和工具(2)
    【软件构造】第二章 软件构建的过程和工具(1)
    【软件构造】第一章 软件构造基础(2)
    【软件构造】第一章 软件构造基础(1)
    机器学习技法笔记-Lecture 1 Linear support vector machine
    机器学习基石笔记-Lecture 15 Validation
  • 原文地址:https://www.cnblogs.com/hehe54321/p/9710074.html
Copyright © 2020-2023  润新知