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