POJ1066:线段交点

POJ1066

题解

  • 方法很简单,就是边界上的每一个结点与终点的连线,与图中线段的交点的个数。最后还要加1,因为边界也要炸。
  • 为什么这样子呢?因为只有跨越端点的时候才会改变交点数量。

代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
using namespace std;
double const eps = 1e-8;
int const inf = 0x7f7f7f7f;
int const N = 30 + 5;
int n,ans;
vector<double>G[5];
typedef struct Point{   //点和向量
	double x,y;
	Point(){};
	Point(double x,double y):x(x),y(y){};
	Point operator - (const Point& e)const{   //减
		return Point(x - e.x,y - e.y);
	}
	double operator ^ (const Point& e)const{  //叉乘
		return x * e.y - y * e.x;
	}
	double operator * (const Point& e)const{  //点积
		return x * e.x + y * e.y;
	}
}Vector;
Point des;
struct Line{    //直线的定义
	Point a,b;
	Line(){};
	Line(Point a,Point b):a(a),b(b){}
}line[N],tmp;
int dcmp(double x){    //判断符号
	if(fabs(x) < eps)	return 0;
	else return x < 0 ? -1 : 1;
}
bool segment_intersection(Line line1,Line line2){  //判断线段是否相交,相交返回true
	double c1 = (line1.b - line1.a) ^ (line2.a - line1.a);
	double c2 = (line1.b - line1.a) ^ (line2.b - line1.a);
	double c3 = (line2.b - line2.a) ^ (line1.a - line2.a);
	double c4 = (line2.b - line2.a) ^ (line1.b - line2.a);
	return dcmp(c1) * dcmp(c2) < 0 && dcmp(c3) * dcmp(c4) < 0;
}
void Init(int x1,int y1){
	if(y1 == 0)	G[1].push_back(x1);
	if(y1 == 100)	G[3].push_back(x1);
	if(x1 == 0)	G[4].push_back(y1);
	if(x1 == 100)	G[2].push_back(y1);
}
int solve(Line l){
	int res = 0;
	for(int i=0;i<n;i++)
		if(segment_intersection(l,line[i]))	res++;
	return res;
}
int main(){
	while(~scanf("%d",&n)){
		for(int i=1;i<=4;i++){
			G[i].clear();
			G[i].push_back(0),	G[i].push_back(100);
		}
		for(int i=0;i<n;i++){
			double x1,y1,x2,y2;
			scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
			line[i] = Line(Point(x1,y1),Point(x2,y2));
			Init(x1,y1);
			Init(x2,y2);
		}
		scanf("%lf%lf",&des.x,&des.y);
		ans = inf;
		for(int i=1;i<=4;i++){
			for(int j=0;j<G[i].size();j++){
				if(i == 1)	tmp = Line(Point(G[i][j],0),des);
				if(i == 2)	tmp = Line(Point(100,G[i][j]),des);
				if(i == 3)	tmp = Line(Point(G[i][j],100),des);
				if(i == 4)	tmp = Line(Point(0,G[i][j]),des);
				ans = min(ans,solve(tmp));
			}
		}
		printf("Number of doors = %d\n",ans + 1);
	}
	return 0;
}

 

posted @ 2019-03-31 20:11  月光下の魔术师  阅读(12)  评论(0)    收藏  举报