POJ 3304 Segmentos (+ segmentos de pensamento e julgamento linha recta relação de intersecção)

tópico Ligue

Dado n segmentos no espaço bidimensional, escrever um programa, o qual determina se existe uma linha de tal forma que depois se projecta estes segmentos em que, todos projectada segmentos têm, pelo menos, um ponto em comum.

Entrada
de entrada começa com um número T mostrando o número de casos de teste e, em seguida, casos de teste T seguir. Cada caso de teste começa com uma linha contendo um número inteiro positivo n ≤ 100 que mostra o número de segmentos. Depois disso, n linhas contendo quatro números reais x1 x2 y2 y1 acompanhamento, em que (x1, y1) e (x2, y2), são as coordenadas dos dois pontos finais para um dos segmentos.

Saída
Para cada caso de teste, seu programa deve saída “Sim!”, Se uma linha com a propriedade desejada existe e saída deve “Não!” de outra forma. Você deve assumir que os dois números de ponto flutuante a e b são iguais se | a - b | <10-8.

1. Título é simples: um dado segmento n, determina se existe um bidimensional sistema de coordenadas de tal modo que todos os segmentos em linha recta para se encontram projectados na cruza-se em linha recta, pelo menos, um ponto

2. Pense sobre o primeiro desenhar uma linha reta, e assumindo o pior caso, se todos os projetada apenas um ponto, apenas um segmento de construção poucos, você vai encontrar lá é uma linha no final de uma linha reta através do ponto projetado. E, em seguida, expandidos para um período de segmento de projecção repetido, e configurado para satisfazer as condições de alguns dos segmentos de linhas, os pontos de extremidade de segmento de linha pode ser encontrado que as duas linhas rectas através de todos os segmentos de linha. E dado o número de segmentos não é muito, negrito enumerate especulação qualquer linha reta direta composto por dois terminais se que passar por todos os segmentos

3. O método de determinação da linha e linhas retas se cruzam, é um teste de rejeição rápida, eu calcular o final de geometria de entrada existe uma linha reta e uma variedade de questões blogue , o maior poço esta pergunta é que pode haver segmentos compartilham um ponto final, sabemos enumerar juiz especial se os dois deve repetir o ponto, mas o método a seguir não é, claramente, porque não é apenas para garantir que a própria enumeração, mas também ponto atrás repetiu que pode ocorrer usando este método a menos discreta

for(int i=0;i<num && !flag;i++)
	for(int j=0;j<i && !flag;j++)

código:

#include <iostream>
#include <math.h>
using namespace std;
#define Point Vector
#define Line Seg
const double eps=1e-8;

int dcmp(double d){
    if(fabs(d)<eps) return 0;
    if(d>0) return 1;
    return -1;
}

struct Point{
    double x,y;
    Point(double x=0,double y=0):x(x),y(y){}
    Point operator + (Point p){ return Point(x+p.x,y+p.y); }
    Point operator - (Point p){ return Point(x-p.x,y-p.y); }
    Point operator * (double d){ return Point(x*d,y*d); }
    double operator * (Point p){ return x*p.x+y*p.y; }
    Point operator / (double d){ return Point(x/d,y/d); }
    double operator ^ (Point p){ return x*p.y-y*p.x; }
    bool operator == (const Point &p) const { return dcmp(x-p.x)==0 && dcmp(y-p.y)==0; }
};

double dis(Point a,Point b){
    return sqrt((b-a)*(b-a));
}

struct Line{
    Point p,q;
    Vector v;
    Line(){}
    Line(Point a,Point b){
        p=a,q=b,v=b-a;
    }
};

bool isOnLine(Point p,Line l){
    return dcmp((l.p-p)^(l.q-p))==0?true:false;
}

bool isSegLineInter(Seg s,Line l){
    double c1=l.v^(s.p-l.p),c2=l.v^(s.q-l.p);
    return dcmp(c1)*dcmp(c2)<=0;
}

Point t[1005];
Seg s[200];

int main()
{
    int kase,n;
    double a,b,c,d;
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>kase;
    while(kase--){
        cin>>n;
        int num=0,cnt=0;
        Point aa,bb;
        while(n--){
            cin>>a>>b>>c>>d;
            aa=Point(a,b),bb=Point(c,d);
            t[num++]=aa;
            t[num++]=bb;
            s[cnt++]=Line(aa,bb);
        }
        int flag=0;
        for(int i=0;i<num && !flag;i++){
            for(int j=0;j<num && !flag;j++){
                if(dcmp(dis(t[i],t[j]))==0) continue;  //坑!!!
                flag=1;
                Line l=Line(t[i],t[j]);
                for(int k=0;k<cnt;k++){
                    if(!isSegLineInter(s[k],l)){
                        flag=0;
                        break;
                    }
                }
            }
        }
        if(flag) cout<<"Yes!\n";
        else cout<<"No!\n";
    }

    return 0;
}
Publicado 127 artigos originais · ganhou elogios 7 · vista 5238

Acho que você gosta

Origin blog.csdn.net/qq_44691917/article/details/104824049
Recomendado
Clasificación