https://www.luogu.com.cn/problem/P4557

  • 题目描述很简单,给定两个凸包,我们设为a,ba,ba,b,现在问给bbb凸包一个整体偏移,偏移量为k→\overrightarrow{k}k,给定k→=(x,y)\overrightarrow{k}=(x,y)k=(x,y),问这两个凸包有没有公共部分
  • 换句话说,就是问给定的k→\overrightarrow{k}k是否满足b+k→=ab+\overrightarrow{k}=ab+k=a,即k→=a−b\overrightarrow{k}=a-bk=a−b

首先介绍一下闵可夫斯基和
定义:两个欧几里得空间点集的和,也称作两个空间的膨胀集,点集AAA与BBB的闵可夫斯基和定义为A+B={a+b,a∈A,b∈B}A+B=\{a+b,a\in A,b\in B\}A+B={a+b,a∈A,b∈B}

  • 求取方法是把这两个空间内部所有的向量按照极角排序,然后找到一个起点,按照极角从小到大依次放边,最后构成的形状就是两个空间的闵可夫斯基和

那么这道题我们其实要求的是aaa和−b-b−b的闵可夫斯基和,只要k→\overrightarrow{k}k终点在两个空间的膨胀集内部,或者边界,就说明会发生冲突,否则不会

  • 什么叫做凸集?凸集的几何意义是如果一个集合任意两个元素连线上的点也在集合内部,那么这个集合就是一个凸集,如下图,左侧是一个凸集但是右侧却不是一个凸集;代数定义是对于SSS的子集内的所有xxx和yyy,并且在区间[0,1][0,1][0,1]内所有的值ttt,如果点(1−t)x+ty(1-t)x+ty(1−t)x+ty也属于SSS,那么SSS就是一个凸集
  • 那么这里产生了一个疑问,为什么两个凸集的闵可夫斯基和仍然是一个凸集?我们可以进行如下证明,设A,BA,BA,B是两个凸集,设C=A+B,α1,α2∈A,β1,β2∈BC=A+B,\alpha_1,\alpha_2\in A,\beta_1,\beta_2\in BC=A+B,α1​,α2​∈A,β1​,β2​∈B
  • 由于(1−t)α1+tα2∈A(1-t)\alpha_1+t\alpha_2\in A(1−t)α1​+tα2​∈A,(1−t)β1+tβ2∈B(1-t)\beta_1+t\beta_2\in B(1−t)β1​+tβ2​∈B,所以根据凸集和的定义有(1−t)α1+tα2+(1−t)β1+tβ2∈C(1-t)\alpha_1+t\alpha_2+(1-t)\beta_1+t\beta_2\in C(1−t)α1​+tα2​+(1−t)β1​+tβ2​∈C
  • 所以(1−t)(α1+β1)+t(α2+β2)∈C(1-t)(\alpha_1+\beta_1)+t(\alpha_2+\beta_2)\in C(1−t)(α1​+β1​)+t(α2​+β2​)∈C又因为根据凸集和的定义有α1+β1∈C,α2+β2∈C\alpha_1+\beta_1\in C,\alpha_2+\beta_2\in Cα1​+β1​∈C,α2​+β2​∈C,这就证明了C是一个凸集

接下来回到这道题,梳理一下思路,我们首先要求出AAA和−B-B−B两个凸集的闵可夫斯基和,这个结果是一个凸包,求闵可夫斯基和我们可以使用固定一个初始点然后进行归并,始终把外面的线加进去,这里使用向量叉积来判断线是否在外部,−B-B−B的意思就是坐标都取相反数,算出来要再跑一次AndrewAndrewAndrew防止出现共线,然后进行点是否在凸包内部的二分判定,程序如下

#include <bits/stdc++.h>using namespace std;
#define db double
const db eps = 1e-10;
const int MAXN = 1e5 + 100;
int sgn(db x){if(fabs(x) < eps) return 0;return x < 0 ? -1 : 1;
}
struct Point{db x, y;Point(){}Point(db x, db y): x(x), y(y){}Point operator + (const Point &B)const{return Point(x + B.x, y + B.y);}Point operator - (const Point &B)const{return Point(x - B.x, y - B.y);}bool operator < (const Point &B)const{return sgn(x - B.x) < 0 || (sgn(x - B.x) == 0 && sgn(y - B.y) < 0);}bool operator == (const Point &B)const{return sgn(x - B.x) == 0 && sgn(y - B.y) == 0;}
}s1[MAXN], s2[MAXN], ch1[MAXN], ch2[MAXN];
Point M[MAXN], ans[MAXN];
typedef Point Vector;
db Cross(Vector A, Vector B){return A.x * B.y - A.y * B.x;
}
int Convex_hull(Point *s, Point *ch, int n){int v = 0;sort(s, s + n);n = unique(s, s + n) - s;for(int i=0;i<n;i++){while(v > 1 && sgn(Cross(ch[v - 1] - ch[v - 2], s[i] - ch[v - 2])) <= 0){v -= 1;}ch[v++] = s[i];}int j = v;for(int i=n-2;i>=0;i--){while(v > j && sgn(Cross(ch[v - 1] - ch[v - 2], s[i] - ch[v - 2])) <= 0){v -= 1;}ch[v++] = s[i];}if(n > 1) v -= 1;return v;
}
int check(Point A, Point *ch, int n){int l = 0;int r = n - 1;while(r - l > 1){int mid = ((r - l) >> 1) + l;db a1 = Cross(ch[mid] - ch[0], A - ch[0]);db a2 = Cross(ch[mid + 1] - ch[0], A - ch[0]);if(sgn(a1) >= 0 && sgn(a2) <= 0){if(sgn(Cross(ch[mid + 1] - ch[mid], A - ch[mid])) >= 0) return 1;return 0;}else if(sgn(a1) < 0){r = mid;}else{l = mid;}}return 0;
}
int Minkowski_sum(int n, int m){int tot;for(int i=1;i<n;i++){s1[i] = ch1[i] - ch1[i - 1];}s1[n] = ch1[0] - ch1[n - 1];for(int i=1;i<m;i++){s2[i] = ch2[i] - ch2[i - 1];}s2[m] = ch2[0] - ch2[m - 1];ans[tot = 0] = s1[0] + s2[0];int pt1, pt2;pt1 = pt2 = 1;while(pt1 <= n && pt2 <= m){tot += 1;ans[tot] = ans[tot - 1] + (sgn(Cross(s1[pt1], s2[pt2])) >= 0 ? s1[pt1++] : s2[pt2++]);}while(pt1 <= n){tot += 1;ans[tot] = ans[tot - 1] + s1[pt1++];}while(pt2 <= m){tot += 1;ans[tot] = ans[tot - 1] + s2[pt2++];}return tot;
}
int main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int n, m, q;db x, y;cin >> n >> m >> q;for(int i=0;i<n;i++){cin >> s1[i].x >> s1[i].y;}int a = Convex_hull(s1, ch1, n);for(int i=0;i<m;i++){cin >> s2[i].x >> s2[i].y;s2[i].x = -s2[i].x;s2[i].y = -s2[i].y;}int b = Convex_hull(s2, ch2, m);int c = Minkowski_sum(a, b);c = Convex_hull(ans, M, c);while(q--){cin >> x >> y;cout << check(Point(x, y), M, c) << '\n';}return 0;
}

P4557 [JSOI2018]战争 凸包的闵可夫斯基和相关推荐

  1. [JSOI2018] 战争(闵可夫斯基和 + 二分)

    题意 给出两个凸包 A,BA,BA,B,有 qqq 次询问,每次询问给出向量 (dx,dy)(dx,dy)(dx,dy),问 BBB 所有点移动 (dx,dy)(dx,dy)(dx,dy) 是否与 A ...

  2. 【计几】闵可夫斯基和 二分判断点是否在凸包内

    闵可夫斯基和算法(时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn)) 附:二分判断点是否在凸包内(时间复杂度 O ( n l o g n ) O(nlogn) O(nlo ...

  3. 洛谷 P4557 战争:凸包+闵可夫斯基和

    题意: 给出两个凸包AAA和BBB,有若干询问,每次给出一个向量V=(x,y)V = (x,y)V=(x,y),将BBB按照VVV的方向平移到B′B'B′,然后回答AAA和B′B'B′是否相交. 题解 ...

  4. P4557-[JSOI2018]战争【凸包,闵可夫斯基和】

    正题 题目连接:https://www.luogu.com.cn/problem/P4557 题目大意 给出两个点集A,BA,BA,B,qqq次询问给出一个向量vvv,询问将BBB中所有点加上向量vv ...

  5. 闵可夫斯基和(Mincowsky sum)

    一.概述 官方定义:两个图形A,B的闵可夫斯基和C={a+b|a∈A,b∈B} 通俗一点:从原点向图形A内部的每一个点做向量,将图形B沿每个向量移动,所有的最终位置的并便是闵可夫斯基和(具有交换律) ...

  6. Codeforces Round #574 (Div. 2) F. Geometers Anonymous Club (闵可夫斯基求和)

    题目链接:http://codeforces.com/contest/1195/problem/F 题意:现在有nnn个凸包,标号分别为1−n1-n1−n给出所有的顶点坐标,有qqq次询问,每次询问给 ...

  7. 【模板/经典题型】闵可夫斯基和

    闵可夫斯基和,是两个欧几里得空间的点集的和,以德国数学家闵可夫斯基命名. 点集A与B的闵可夫斯基和就是{o|o=a+b},其中a属于A,b属于B. 对于凸包这种特殊的图形,它的闵可夫斯基和有一些较好的 ...

  8. CF1019E Raining season

    https://www.luogu.org/problemnew/show/CF1019E 题解 \[ dis=day*a+b \] \[ b=-day*a+dis \] 然后就变成了斜率优化. 考虑 ...

  9. 数论六之计算几何干货——计算几何模板解释全集 及 模板检验训练场

    文章目录 点和向量及运算 直线和线段 求解点到直线的距离/点在直线上 求解点到线段的距离/点在线段上 求解两条线段是否相交 求解两直线的交点 多边形 求解多边形面积 求解多边形重心 求解判断定点与多边 ...

最新文章

  1. 精通python爬虫框架-精通Python爬虫框架Scrapy.pdf
  2. 对于基础太模糊下一步需要清晰 几个目标
  3. C/C++实现sleep函数
  4. QT绘制水平百分比条形图。
  5. 英语美句-每日积累-02
  6. 微软智能语音多情感技术升级,晓晓中文语音突破14种风格
  7. poj 3321 Apple Tree 树状数组
  8. Info.plist信息
  9. 2016服务器系统驱动,windows sever2016驱动大家是怎么装的啊
  10. centos----tftpd配置
  11. 科学计算机恢复初始化,快速解决Windows 10系统还原一直初始化或卡住的方法!...
  12. 控制反转和依赖注入的个人理解
  13. java memcmp_【转】 memcmp源码实现
  14. python access violation_Python x64下ctypes动态链接库出现access violation的原因分析
  15. 理解inux 下 intel处理器睿频
  16. mysql 设置密码出现ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
  17. stm8 ADC中断采集
  18. HTTP性能极限优化
  19. 多线程、并发/并行、自定义线程类、线程安全、守护线程、定时器、线程状态、线程池
  20. 百度Apollo仿真仿真平台搭建-附1

热门文章

  1. 亲测:大蒜的用处止咳用法
  2. RocketMQ学习(四)——RocketMQ消息发送
  3. 鲁鹏老师三维重建课程之单视图重建
  4. 人参皂苷rh2哪里买正规?
  5. Python, Cython绘制美妙绝伦的Mandelbrot集, 曼德博集分形图案
  6. python log壁纸_一个爬取Bing每日壁纸的python脚本
  7. 数据库| 删除数据库表
  8. VScode 中的 Mysql 相关插件使用
  9. 【Python3.6爬虫学习记录】(九)模拟登陆QQ空间爬取好友所有留言并制作词云
  10. Linux 安装Zabbix5.0超详细教程