CodeForces 166B (凸包)

求一个多边形是否完全在另一个凸多边形内。

乍一看,好像要判点在多边形内,但复杂度不允许,仔细一想,可以把两个多边形的点混起来求一个共同的凸包,如果共同的凸包依旧是原来凸包上的点,说明是。

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 using namespace std;
 11 #define N 200010
 12 #define LL long long
 13 #define INF 0xfffffff
 14 const double eps = 1e-8;
 15 const double pi = acos(-1.0);
 16 const double inf = ~0u>>2;
 17 struct point
 18 {
 19     double x,y;
 20     int flag;
 21     point(double x=0,double y=0):x(x),y(y){}
 22 }p[N],ch[N],q[N];
 23 typedef point pointt;
 24 point operator -(point a,point b)
 25 {
 26     return point(a.x-b.x,a.y-b.y);
 27 }
 28 int dcmp(double x)
 29 {
 30     if(fabs(x)<eps) return 0;
 31     return x<0?-1:1;
 32 }
 33 double cross(point a,point b)
 34 {
 35     return a.x*b.y-a.y*b.x;
 36 }
 37 double mul(point a,point b,point c)
 38 {
 39     return cross(b-a,c-a);
 40 }
 41 double dis(point a)
 42 {
 43     return sqrt(a.x*a.x+a.y*a.y);
 44 }
 45 bool cmp(point a,point b)
 46 {
 47     if(mul(p[0],a,b)==0)
 48     return dis(p[0]-a)<dis(p[0]-b);
 49     return mul(p[0],a,b)>0;
 50 }
 51 int Graham(int n)
 52 {
 53     int i,k = 0,top;
 54     point tmp;
 55     for(i = 0 ; i < n; i++)
 56     {
 57         if(p[i].y<p[k].y||(p[i].y==p[k].y&&p[i].x<p[k].x))
 58             k = i;
 59     }
 60     if(k!=0)
 61     {
 62         tmp = p[0];
 63         p[0] = p[k];
 64         p[k] = tmp;
 65     }
 66     sort(p+1,p+n,cmp);
 67     ch[0] = p[0];
 68     ch[1] = p[1];
 69     top = 1;
 70     for(i = 2; i < n ; i++)
 71     {
 72         while(top>0&&dcmp(mul(ch[top-1],ch[top],p[i]))<0)
 73             top--;
 74         top++;
 75         ch[top] = p[i];
 76     }
 77     return top;
 78 }
 79 int dot_online_in(point p,point l1,point l2)
 80 {
 81     return !dcmp(mul(p,l1,l2))&&(l1.x-p.x)*(l2.x-p.x)<eps&&(l1.y-p.y)*(l2.y-p.y)<eps;
 82 }
 83 int main()
 84 {
 85     int n,m,i;
 86     cin>>n;
 87     for(i =0 ; i < n; i++)
 88     {
 89         scanf("%lf%lf",&p[i].x,&p[i].y);
 90         p[i].flag = 0;
 91     }
 92     cin>>m;
 93     for(i = n ; i < n+m; i++)
 94     {
 95         scanf("%lf%lf",&p[i].x,&p[i].y);
 96         p[i].flag = 1;
 97         q[i-n] = p[i];
 98     }
 99     int tn = Graham(n+m);
100     ch[tn+1] = ch[0];
101     int ff = 1;
102     for(i = 0 ; i < m ; i++)
103     {
104         if(dot_online_in(q[i],ch[tn],ch[tn+1]))
105         {
106             ff  = 0;
107             //cout<<p[i].x<<" "<<p[i].y<<endl;
108             break;
109         }
110     }
111     if(!ff)
112     {
113         puts("NO");
114         return 0;
115     }
116     for(i = 0; i <= tn ; i++)
117     if(ch[i].flag) {ff = 0;break;}
118     if(ff) puts("YES");
119     else puts("NO");
120     return 0;
121 }

时间: 2024-07-30 21:32:45

CodeForces 166B (凸包)的相关文章

Codeforces 50C Happy Farm 5 凸包

题目链接:点击打开链接 == 难得的y出了一道计算几何.. #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <iostream> using namespace std; #define INF 999999999.9 #define PI acos(-1.0) #define ll long long struct Poi

Codeforces Gym 100492A(凸包,巧妙算法)

题意:给一个凸包,含有N个点,求删除每个点后再求凸包,凸包上的点的平均值.以p/q的最简形式输出,起初q=N.题目要求凸包不允许有两条相邻边平行. 链接:http://codeforces.com/gym/100492 A题 解法:咋一看没啥思路,可能会想到枚举删除每个点,其左边的点到右边的点再求一次凸包 这样的方法,虽然复杂度依然是O(N)的,但是这样编码起来极其困难,而且容易写挂.多想一想,发现只需求若干次凸包即可,正解如下.先求一次凸包,假设凸包上有偶数个点1..n,接下来,每两个点间接着

Codeforces 605C Freelancer&#39;s Dreams 凸包

Freelancer's Dreams 我们把每个二元组看成是平面上的一个点, 那么两个点的线性组合是两点之间的连线, 即x * (a1, b1) + y * (a1, b1) && x + y == 1, 那么n个点的线性组合就是一个凸包, 那么我们求出凸包和(0, 0)到(p, q)直线的交的那个较大值就是最优的组合平均速度. 需要注意的是, 直线和凸包可能没有交点, 需要加入(maxa, 0), (0, maxb)这两个点. #include<bits/stdc++.h>

Codeforces Round #549 (Div. 2) F 数形结合 + 凸包(新坑)

https://codeforces.com/contest/1143/problem/F 题意 有n条形如\(y=x^2+bx+c\)的抛物线,问有多少条抛物线上方没有其他抛物线的交点 题解 \(y=x^2+bx+c=>y+x^2=bx+c\),转换为点\((x,y+x^2)\)在bx+c的直线上 两个点确定一条抛物线,同时也确定了一条直线 需要选择最上面那些点相邻确定的抛物线,所以维护一个上凸包即可 维护上凸包,当前点在前进方向左边需要向后退,cross(a,b)>=0 代码 #inclu

Codeforces 1045E. Ancient civilizations 构造 计算几何 凸包

原文链接https://www.cnblogs.com/zhouzhendong/p/CF1045E.html 4K码量构造题,CF血腥残暴! 题解 首先,如果所有点颜色相同,那么直接连个菊花搞定. 然后我们建个凸包. 如果凸包上有大于2段颜色(就是至少四段),比如这样 那么必然无解. 否则就只有一段颜色或者两段颜色: 这里我们先不管这个,考虑一个三角形的构造. 考虑三角形三个顶点颜色不全相同的情况,例如: (两个白点的情况是等价的) 假如三角形区域内没有白点,那么直接全部连到其中一个黑点就好了

Codeforces gym102222 B.Rolling The Polygon 凸包/余弦定理

题意: 有一个不保证凸的多边形,让你滚一圈,计算某点滚出的轨迹多长. 题解: 求出凸包后,以每个点为转轴,转轴到定点的距离为半径,用余弦定理计算圆心角,计算弧长. #include<iostream> #include<cstdio> #include<cmath> #include<cstring> using namespace std; int main() { int t,case1=0; cin>>t; while(t--) { cas

codeforces 536 c Tavas and Pashmaks

题意: 在一个运动比赛中有两种跑道,现在有n个选手,给出每个选手的在两种跑道上的速度,(ui,vi),求哪些选手可能赢得比赛. 限制: 1 <= n <= 2*1e5 思路: 维护一个类似凸包的一段. /*codeforces 536 c Tavas and Pashmaks 题意: 在一个运动比赛中有两种跑道,现在有n个选手,给出每个选手的在两种跑道上的速度,(ui,vi),求哪些选手可能赢得比赛. 限制: 1 <= n <= 2*1e5 思路: 维护一个类似凸包的一段. */

CodeForces Beta Round #1

Codeforces Beta Round #1 A. Theatre Square [题意]一个n*m的矩形广场,用a*a的方形石板铺设,问最少需要多少块石板能铺满广场. [思路]水题,从n方向来看能能够铺设ceil(n/a)块,从m方向来看能能够铺设ceil(m/a)块,总共有ceil(n/a)*ceil(m/a)块. 1 /* 2 ** CodeForces 1A Theatre Square 3 ** Created by Rayn @@ 2014/05/18 4 */ 5 #inclu

动态凸包 学习总结

动态凸包就是可以支持动态插入点,维护凸包信息的一类问题 又考到了,又被炸飞了(然而其实弱的连凸包性质都看不出来 注意只能支持动态插入点,而不支持动态删除和插入 不过删除的话如果不强制在线反过来就是插入啊OwO 不是很喜欢水平序的动态凸包,因为要维护上下两个凸壳好烦 所以就学了一发极角序 大概做法是以极角序为键值用平衡树维护凸包上的点 每次插入的时候找到插入点的前驱后继,用叉积判断是否在内部 如果不在就插入,插入之后不断的判断插入后前驱是否在凸包内和后继是否在凸包内 并且不断的删除直至不能删除为止