POJ 3304 Segmentos (+ segmentos de pensamiento y el juicio de línea recta de intersección relación)

tema Enlace

Dado n segmentos en el espacio de dos dimensiones, escribir un programa, que determina si existe una línea de tal manera que después de la proyección de estos segmentos en él, todo proyectado segmentos tienen al menos un punto en común.

De entrada
de entrada comienza con un número T que muestra el número de casos de prueba y, a continuación, los casos de prueba T siguen. Cada caso de prueba comienza con una línea que contiene un número entero positivo n ≤ 100 que muestra el número de segmentos. Después de eso, n líneas que contienen cuatro números reales x1 y1 seguimiento x2 y2, en el que (x1, y1) y (x2, y2) son las coordenadas de los dos puntos finales para uno de los segmentos.

Salida
Para cada caso de prueba, el programa de salida debe “Sí!”, Si una línea con la propiedad deseada existe y salida deben “¡No!” de otra manera. Debe suponer que los dos números de punto flotante A y B son iguales si | a - b | <10-8.

1. Título es simple: un segmento dado n, determina si hay un sistema bidimensional de coordenadas tal que todos los segmentos de línea recta para satisfacer proyectan en las intersecciones de línea recta al menos un punto

2. Piense en la primera dibujar una línea recta, y suponiendo que el peor de los casos, si todo el proyectado sólo un punto, sólo un segmento de la construcción pocos, se dará cuenta de que hay una línea al final de una línea recta a través del punto proyectado. Y entonces se expandió en un período de segmento de proyección repetida, y configurado para satisfacer las condiciones de algunos de los segmentos de línea, los puntos finales segmento de línea se pueden encontrar que las dos líneas rectas a través de todos los segmentos de línea. Y teniendo en cuenta el número de segmentos no es mucho, enumerar la especulación audaz cualquier línea recta directa compuesto por dos puntos finales ya sea para ir a través de todos los segmentos

3. El método de determinación de la línea y las líneas rectas de intersección, es una prueba de rechazo rápido, calculo el que concluye la geometría de entrada no es una línea recta y una variedad de temas de un blog , el pozo más grande de esta pregunta es que puede haber segmentos comparten un punto final, sabemos de enumeración juez especial si los dos deben repetir el punto, pero el siguiente método es claramente no, porque no es sólo para asegurar que la enumeración en sí, sino también punto por detrás repetido que se puede producir 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;
}
Publicados 127 artículos originales · ganado elogios 7 · vistas 5238

Supongo que te gusta

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