欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【POJ1066】【UVA754】【计算几何】Treasure Hunt

程序员文章站 2022-04-02 17:41:55
...

【题目描述】

【解析】

  • 这道题有些类似最短路,但终点不确定。
  • 于是想到:虽然题目中要求通过每一个区间的中点,但实际上走这一区间的任意一个点都是一样的,因此只需要枚举每堵墙的端点。
  • 此时,路线已经确定,由于数据范围很小,直接枚举与每堵墙是否相交,用叉积判断即可。
  • 此题坑点众多:
    • poj 上不能使用bits库
    • 需要特判n=1时的情况
    • 最后不要忘记还要加上外墙
    • UVA上的题为多组数据,且2组数据之间要加上一行空格,POJ上的题为单组数据

【代码】

  • 此处给出POJ AC代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<queue>//注意:poj中不能使用bits
using namespace std;
inline int read(){
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
	return x*f;
}
const int N=50;
const double eps=1e-10;
struct Point{
	double x,y;
}l[N],p[5][N],q,p1[N],p2[N];
double operator^(Point a,Point b){return a.x*b.y-a.y*b.x;}//叉积
Point operator-(Point a,Point b){return (Point){a.x-b.x,a.y-b.y};}
int T,n,cnt[5];
inline int Inter(Point a1,Point b1,Point a2,Point b2){
	if(((a2-a1)^(b2-a1))*((a2-b1)^(b2-b1))<0&&(((a1-a2)^(b1-a2))*((a1-b2)^(b1-b2)))<0)
		return 1;
	return 0;
}//判断2条线段是否相交
int main(){
	n=read();
	if(n==0){
		printf("Number of doors = 1\n");
		return 0; 
	}//特判n=0
	queue<Point>t;
	for(int i=1;i<=n;++i){
		int a1=read(),b1=read(),a2=read(),b2=read();
		l[i]=(Point){a2-a1,b2-b1};	
		p1[i]=(Point){a1,b1};
		p2[i]=(Point){a2,b2};
		t.push(p1[i]);t.push(p2[i]);
	}	
	scanf("%lf%lf",&q.x,&q.y);
	int ans=1e9; 
	while(!t.empty()){
		Point u=t.front();t.pop();
		int ret=0;
		for(int i=1;i<=n;++i) 
			ret+=Inter(u,q,p1[i],p2[i]);
		ans=min(ans,ret+1);
	}//枚举终点
	printf("Number of doors = %d\n",ans);
	return 0;
}