题意:从外面到达宝藏所走的最少的门。
思路:枚举边上的点。
AC代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <stack>
#include <queue>
#include <vector>
#include <cmath>
#include <map>
#include <set>
#define ll long long
#define llu unsigned long long
using namespace std;
const double eps = 1e-8;
struct Point {
double x,y;
Point (double x = 0,double y = 0) : x(x),y(y) {}
};
Point p[150];
struct Line{
Point a,b;
};
Line line[100];
int indl,indp;
bool dcmp(double x) {
if(fabs(x)-0.0 <= eps) return true;
return false;
}
double dis(Point a,Point b) {
return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}
double cross(Point a,Point b,Point c) {
if(dcmp((b.x-a.x)*(c.y-a.y) - (c.x-a.x)*(b.y-a.y))) return 0;
return ((b.x-a.x)*(c.y-a.y) - (c.x-a.x)*(b.y-a.y));
}
bool f(Point a,Point b,Point c,Point d) {
if(min(a.x,b.x)<=max(c.x,d.x) && min(c.x,d.x)<=max(a.x,b.x)
&& min(a.y,b.y)<=max(c.y,d.y) && min(c.y,d.y)<=max(a.y,b.y)) return true;
return false;
}
int pd(Point a,Point b){
int ans = 0;
for(int i=1;i<indl; i++) {
if(f(a,b,line[i].a,line[i].b)){
// cout<<22222<<endl;
if(cross(a,b,line[i].a)*cross(a,b,line[i].b) <= 0
&& cross(line[i].a,line[i].b,a)*(cross(line[i].a,line[i].b,b)) <= 0) {
// cout<<1111<<endl;
ans++;
}
}
}
// cout<<ans<<endl;
return ans;
}
int main(){
int n;
Point A,B,C;
double a,b,c,d;
scanf("%d",&n);
indl = 1,indp = 1;
for(int i=1;i<=n;i++) {
scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
p[indp].x = a; p[indp].y = b;
indp++;
p[indp].x = c; p[indp].y = d;
indp++;
A.x = a; A.y = b;
B.x = c; B.y = d;
line[indl].a = A;
line[indl].b = B; indl++;
}
scanf("%lf%lf",&C.x,&C.y);
if(n == 0) {
printf("Number of doors = 1\n"); return 0;
}
int Min = 1000000;
for(int i=1;i<indp;i++) {
int f = 0;
for(int j=1; j<indp; j++) {
if(i!=j) {
if((dcmp(p[i].x-p[j].x)&&dcmp(p[i].y-p[j].y))){
f = 1; break;
}
}
}
if(f) continue;
// cout<<i<<" "<<pd(p[i],C)<<endl;
Min = min(Min,pd(p[i],C));
}
printf("Number of doors = %d\n",Min);
return 0;
}