Poj-3304 (Cross product judges whether the straight line crosses the line segment)

topic

http://poj.org/problem?id=3304 The
meaning of the question is probably to give some line segments, and ask if you can find a straight line so that the intersection of these line segments on the straight line is not empty.
The number of line segments is not more than 100.

analysis

  • If the intersection of the projections is not empty, then at least one straight line perpendicular to that straight line can pass through all the line segments.
  • And it can be said that as long as there is a solution, there must be a solution that passes through certain two endpoints. (Because the straight line is limited by these end points, it must be an end point at the boundary)
  • Then enumerate the endpoints to make a straight line, and then judge whether it passes through all the selections.

program

#include <cstdio>
#include <cmath>
using namespace std;
double k1,k2;
int n,T,ok;

struct node{
   
   double x,y;} U[1000],V[1000];
bool equ(node A,node B){
   
   return abs(A.x-B.x)<=0.00000001 && abs(A.y-B.y)<=0.00000001;}
bool Equ(double x,double y){
   
   return abs(x-y)<=0.00000001;}
double cheng(node v1,node v2){
   
   return v1.x*v2.y-v2.x*v1.y;}
bool check(node u,node v){
    if (equ(u,v)) return 0;
    for (int i=1; i<=n; i++){
        if (equ(u,U[i]) || equ(u,V[i]) || equ(v,U[i]) || equ(v,V[i])) continue;
        k1=cheng((node){U[i].x-u.x,U[i].y-u.y},(node){U[i].x-v.x,U[i].y-v.y});
        k2=cheng((node){V[i].x-u.x,V[i].y-u.y},(node){V[i].x-v.x,V[i].y-v.y});
        if (k1*k2>0) return 0;
    }
    return 1;
}

int main(){
    for(scanf("%d",&T); T--; ok=0){
        scanf("%d",&n);
        for (int i=1; i<=n; i++)
            scanf("%lf%lf%lf%lf",&U[i].x,&U[i].y,&V[i].x,&V[i].y);
        for (int i=1; i<=n && !ok; i++)
            for (int j=i; j<=n && !ok; j++){
                ok=check(U[i],U[j])||check(U[i],V[j])||check(V[i],U[j])||check(V[i],V[j]);
            }
        puts(ok?"Yes!":"No!");
    }
}

prompt

  • I think it is also possible to enumerate an endpoint, suppose a straight line passes this endpoint, and then use other line segments to limit the slope of this line, and see if the acceptable interval of the final slope is empty, but I don’t know why it can’t be passed, the code is below, Please also take a look.
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
struct node{
   
   double x,y;} U[20000],V[20000];
double Max,Min,mn,mx,k1,k2,k3,k4;
int n,ok,T;
double K(node A,node B){
    if (A.x==B.x) return 99999999999999999999999999999.0;
    return (A.y-B.y)/(A.x-B.x);
}
bool equ(node A,node B){
   
   return abs(A.x-B.x)<=0.00000001 && abs(A.y-B.y)<=0.00000001;}
bool dy(double x,double y){
   
   return x-y>0.0001;}
bool xy(double x,double y){
   
   return y-x>0.0001;}
bool check(node O){
    Min=-99999999999999999999999999999.0;
    Max=99999999999999999999999999999.0;
    for (int i=1; i<=n; i++) if(!equ(O,U[i]) && !equ(O,V[i])){
        k1=K(O,U[i]);
        k2=K(O,V[i]);
        mn=min(k1,k2),mx=max(k1,k2);
        if (dy(mn,Max) || xy(mx,Min)) return 0;
        if (xy(mx,Max)) Max=mx;
        if (dy(mn,Min)) Min=mn;
        if (dy(Min,Max)) return 0;
    }
    return 1;
}

int main(){

    for (scanf("%d",&T); T--;){
        ok=0;
        scanf("%d",&n);
        for (int i=1; i<=n; i++) scanf("%lf%lf%lf%lf",&U[i].x,&U[i].y,&V[i].x,&V[i].y);
        for (int i=1; i<=n && !ok; i++)
            if (check(U[i]) || check(V[i])) ok=1;
        puts(ok?"Yes!":"No!");
    }
}

Guess you like

Origin blog.csdn.net/jackypigpig/article/details/78629588