zoukankan      html  css  js  c++  java
  • [JSOI2018]战争

    题目描述

    九条可怜是一个热爱读书的女孩子。

    在她最近正在读的一本小说中,描述了两个敌对部落之间的故事。第一个部落有 nnn 个人,第二个部落有 mmm 个人,每一个人的位置可以抽象成二维平面上坐标为 (xi,yi)(x_i,y_i)(xi,yi) 的点。

    在这本书中,人们有很强的领地意识,对于平面上的任何一个点,如果它被三个来自同一部落的人形成的三角形(可能退化成一条线段)包含(包括边界),那么这一个点就属于这一个部落的领地。如果存在一个点同时在两个阵营的领地中,那么这两个部落就会为了争夺这一个点而发生战争。

    常年的征战让两个部落不堪重负,因此第二个部落的族长作出了一个英明的决定,他打算选择一个向量 (dx,dy)(dx,dy)(dx,dy) ,让所有的族人都迁徙这个向量的距离,即所有第二阵营的人的坐标都变成 (xi+dx,yi+dy)(x_i+dx,y_i+dy)(xi+dx,yi+dy) 。

    现在他计划了 qqq 个迁徙的备选方案,他想要你来帮忙对每一个迁徙方案,计算一下在完成了迁徙之后,两个部落之间还会不会因为争夺领地而发生战争。

    输入格式

    第一行输入三个整数 n,m,qn,m,qn,m,q,表示两个部落里的人数以及迁徙的备选方案数。

    接下来 nnn 行每行两个整数 xi,yix_i,y_ixi,yi​​ 表示第一个部落里的人的坐标。

    接下来 mmm 行每行两个整数 xi,yix_i,y_ixi,yi​​ 表示第二个部落里的人的坐标。

    接下来 qqq 行每行两个整数 dxi,dyidx_i,dy_idxi,dyi​​ 表示一个迁徙方案。

    输入数据保证所有人的坐标两两不同。

    输出格式

    对于每个迁徙方案,输出一行一个整数,000 表示不会发生冲突,111 表示会发生冲突。

    输入输出样例

    输入 #1 
    4 4 3
    0 0
    1 0
    0 1
    1 1
    -1 0
    0 3
    0 2
    0 -1
    0 0
    2 3
    0 -1
    输出 #1
    1
    0
    设a,b为两个部落构成的凸包
    b+d=a等价于d=a-b
    即取反b,求出凸包,再用Minkowski和合并两凸包
    查询用二分查询向量d所在区间,用叉积判断是否在凸包内
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 typedef long long lol;
      7 struct Node
      8 {
      9     lol x,y;
     10     Node operator + (const Node &b) const
     11     {
     12         return (Node){x+b.x,y+b.y};
     13     }
     14     Node operator - (const Node &b) const
     15     {
     16         return (Node){x-b.x,y-b.y};
     17     }
     18 }a[100005],b[100005],sa[200005],sb[200005],sta[200005],bs,s1[200005],s2[200005],s[200005];
     19 int n,m,q,top;
     20 bool cmp(Node a,Node b)
     21 {
     22     if (a.y==b.y) return a.x<b.x;
     23     return a.y<b.y;
     24 }
     25 lol cross(Node a,Node b)
     26 {
     27     return (a.x*b.y-a.y*b.x);
     28 }
     29 lol dist(Node a)
     30 {
     31     return a.x*a.x+a.y*a.y;
     32 }
     33 bool cmp1(Node A,Node B)
     34 {
     35     lol t=cross((a[1]-A),(a[1]-B));
     36     if (t==0) return dist(a[1]-A)<dist(a[1]-B);
     37     return t>0;
     38 }
     39 bool cmp2(Node A,Node B)
     40 {
     41     lol t=cross((b[1]-A),(b[1]-B));
     42     if (t==0) return dist(b[1]-A)<dist(b[1]-B);
     43     return t>0;
     44 }
     45 int grahama(int N)
     46 {int i;
     47     sort(a+1,a+N+1,cmp);
     48     sort(a+2,a+N+1,cmp1);
     49     top=0;
     50     sa[++top]=a[1];
     51     if (N==1) return 1;
     52     sa[++top]=a[2];
     53     for (i=3;i<=N;i++)
     54     {
     55         while (top>1&&cross(a[i]-sa[top-1],sa[top]-sa[top-1])>=0) top--;
     56         top++;
     57         sa[top]=a[i];
     58     }
     59     sa[top+1]=a[1];
     60     return top;
     61 }
     62 int grahamb(int N)
     63 {int i;
     64     sort(b+1,b+N+1,cmp);
     65     sort(b+2,b+N+1,cmp2);
     66     top=0;
     67     sb[++top]=b[1];
     68     if (N==1) return 1;
     69     sb[++top]=b[2];
     70     for (i=3;i<=N;i++)
     71     {
     72         while (top>1&&cross(b[i]-sb[top-1],sb[top]-sb[top-1])>=0) top--;
     73         top++;
     74         sb[top]=b[i];
     75     }
     76     sb[top+1]=b[1];
     77     return top;
     78 }
     79 bool cmpp(Node A,Node B)
     80 {
     81     lol t=cross((s[1]-A),(s[1]-B));
     82     if (t==0) return dist(s[1]-A)<dist(s[1]-B);
     83     return t>0;
     84 }
     85 int grahams(int N)
     86 {int i;
     87     sort(s+1,s+N+1,cmp);
     88     sort(s+2,s+N+1,cmpp);
     89     top=0;
     90     sta[++top]=s[1];
     91     if (N==1) return 1;
     92     sta[++top]=s[2];
     93     for (i=3;i<=N;i++)
     94     {
     95         while (top>1&&cross(s[i]-sta[top-1],sta[top]-sta[top-1])>=0) top--;
     96         top++;
     97         sta[top]=s[i];
     98     }
     99     sta[top+1]=s[1];
    100     return top;
    101 }
    102 bool cmp3(Node A,Node B)
    103 {
    104     return cross(A,B)>0||(cross(A,B)==0&&dist(A)<dist(B));
    105 }
    106 lol find(Node A)
    107 {
    108     if(cross(A,sta[1])>0||cross(sta[top],A)>0) return 0;
    109     lol ps=lower_bound(sta+1,sta+top+1,A,cmp3)-sta-1;
    110     return cross((A-sta[ps]),(sta[ps%top+1]-sta[ps]))<=0;
    111 }
    112 void Minkowski()
    113 {
    114     for(lol i=1;i<n;i++) s1[i]=sa[i+1]-sa[i];s1[n]=sa[1]-sa[n];
    115     for(lol i=1;i<m;i++) s2[i]=sb[i+1]-sb[i];s2[m]=sb[1]-sb[m];
    116     top=1;
    117     s[top]=sa[1]+sb[1];
    118     lol i=1,j=1;
    119     while(i<=n&&j<=m) ++top,s[top]=s[top-1]+(cross(s1[i],s2[j])>=0?s1[i++]:s2[j++]);
    120     while(i<=n) ++top,s[top]=s[top-1]+s1[i++];
    121     while(j<=m) ++top,s[top]=s[top-1]+s2[j++];
    122 }
    123 int main()
    124 {int i,j;
    125 lol dx,dy;
    126     cin>>n>>m>>q;
    127     for (i=1;i<=n;i++)
    128     scanf("%lld%lld",&a[i].x,&a[i].y);
    129     for (i=1;i<=m;i++)
    130     scanf("%lld%lld",&b[i].x,&b[i].y),b[i].x=-b[i].x,b[i].y=-b[i].y;
    131     n=grahama(n);
    132     m=grahamb(m);
    133     Minkowski();
    134     top=grahams(top);
    135     bs=sta[1];
    136     for (i=1;i<=top;i++)
    137     sta[i]=sta[i]-bs;
    138     
    139     for (i=1;i<=q;i++)
    140     {
    141         scanf("%lld%lld",&dx,&dy);
    142         if (find((Node){dx,dy}-bs)) 
    143         printf("1
    ");
    144         else printf("0
    ");
    145     }
    146 } 
  • 相关阅读:
    实战篇之实现 OutLook 中以 EDM 形式发送通知邮件
    ASP.NET MVC5 之路由器
    ASP.NET MVC5 之数据迁移
    说不出的烦
    ASP.NET MVC5 之 Log4Net 的学习和使用
    读取配置文件参数和文件路径
    序列化和反序列化示例
    面向对象之封装
    面向对象4之常用的乱七八糟
    面向对象三之继承和派生
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/11727309.html
Copyright © 2011-2022 走看看