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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值