Problema de casco convexo Codeforces166B

Problema de casco convexo CF166B (modelo)

Link do assunto: http://codeforces.com/problemset/problem/166/B

Pergunta: Dados os n pontos a1, a2 ... an de dois polígonos A e os m pontos b1, b2 ... bm do polígono B, certifique-se de que A é um polígono convexo e julgue se B está completamente contido em A.

Em primeiro lugar, a definição do casco convexo é a seguinte:
Dado um conjunto de pontos em um plano bidimensional, o casco convexo é um polígono convexo formado pela conexão dos pontos mais externos, que podem conter todos os pontos do conjunto de pontos.
por exemplo:
Insira a descrição da imagem aqui

Idéia de resolução de problemas:
você pode usar o método de Andrew para encontrar o casco convexo do polígono A primeiro e obter o conjunto de pontos res do casco convexo e o número de pontos m1; em seguida, coloque todos os pontos do polígono A e B juntos para encontrar todos os pontos a1 , A2 ... an, b1, b2 ... bm, obtenha o conjunto de pontos res2 deste casco convexo e o número de pontos m2. Em seguida, compare m1, m2 e as matrizes de conjunto de dois pontos res e res2.

Se B está em A, colocar o ponto de B no ponto de A não tem efeito em seu
invólucro convexo ----- ➤ Se m1, m2 e res, res2 são iguais, então B está em A, caso contrário B não está em A

Nota: cin será TLE, deve ser alterado para scanf, lembre-se!

Código AC:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<stack>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<cstdlib>
//#include<bits/stdc++.h>
using namespace std;
#define scan(n) scanf("%d",&n)
#define scand(n) scanf("%lf",&n)
#define ll long long
#define eps 1e-8

struct point
{
    
    
	double x,y;
	point() {
    
    } point(double _x,double _y)
	{
    
    
		x=_x;
		y=_y;
	}
	point operator - (const point &b) const
	{
    
    
		return point(x-b.x,y-b.y);
	}
	bool operator < (const point &b) const
	{
    
    
		return x<b.x||x==b.x&&y<b.y;
	}
}res[120005],pa[120005],pb[120005],res2[120005];
//res:得到的凸包的点
//p:原点数组

typedef point Vector;//向量

int dcmp(double x)
{
    
    
	return (x>eps)-(x<-eps);
}

double cross(Vector a,Vector b)//求向量叉乘
{
    
    
	return a.x*b.y-b.x*a.y;
}

int andrew1(struct point p[],int n)
{
    
    
	sort(p,p+n);
	int m=0;
	for (int i=0; i<n; i++)
    {
    
    
		while(m>1&&cross(res[m-1]-res[m-2],p[i]-res[m-2])<0)
            --m;
		res[m++]=p[i];
	}
	int k=m;
	for (int i=n-2; i>=0; --i)
	{
    
    
		while (m>k&&cross(res[m-1]-res[m-2],p[i]-res[m-2])<0)
            --m;
		res[m++]=p[i];
	}
	if (m>1)
        --m;
	return m;//m:凸包中点的个数(下标从0到m-1)
}

int andrew2(struct point p[],int n)
{
    
    
	sort(p,p+n);
	int m=0;
	for (int i=0; i<n; i++)
    {
    
    
		while(m>1&&cross(res2[m-1]-res2[m-2],p[i]-res2[m-2])<0)
            --m;
		res2[m++]=p[i];
	}
	int k=m;
	for (int i=n-2; i>=0; --i)
	{
    
    
		while (m>k&&cross(res2[m-1]-res2[m-2],p[i]-res2[m-2])<0)
            --m;
		res2[m++]=p[i];
	}
	if (m>1)
        --m;
	return m;//m:凸包中点的个数(下标从0到m-1)
}

int main()
{
    
    
    int n,m,i,a,b;
    scan(n);
    for(i=0;i<n;i++)
    {
    
    
        scand(pa[i].x);
        scand(pa[i].y);
        pb[i].x=pa[i].x;
        pb[i].y=pa[i].y;
    }
    int m1=andrew1(pa,n);
    scan(m);
    for(i=0;i<m;i++)
    {
    
    
        scand(pb[i+n].x);
        scand(pb[i+n].y);
    }
    int m2=andrew2(pb,n+m);
    if(m1!=m2)
    {
    
    
        printf("NO\n");
        return 0;
    }
    sort(res,res+m1);
    sort(res2,res2+m2);
    int f=1;
    for(i=0;i<m1;i++)
    {
    
    
        double x1=res[i].x,x2=res2[i].x;
        double y1=res[i].y,y2=res2[i].y;
        if(fabs(x1-x2)<eps&&fabs(y1-y2)<eps)
            continue;
        else
        {
    
    
            f=0;
            break;
        }
    }
    if(f==0)
        printf("NO\n");
    else
        printf("YES\n");
    return 0;
}

Acho que você gosta

Origin blog.csdn.net/qq_40534166/article/details/97962983
Recomendado
Clasificación