Test instructions: Give a 100*100 square region, through a number of connected area boundary segments to divide the square area into a number of irregular polygon small areas, and then give the treasure location, the need to open from the area to the treasure location of a path, so that the path to open up the number of walls needed to be the least ("get through a wall "That is to open a space in the middle of the segment of the wall to connect to the outside world," the output should be the number of walls (including the wall on the border).
Puzzle: Enumerate each entry, in all cases, take the lowest number of walls of the output, enumerate each entry, and do not enumerate the midpoint of each edge, directly enumerate the two vertices of the line segment is the row (because to go through a wall, then from anywhere in the line lines, do not have to go through the midpoint of the line), The vertex of the enumeration is connected to the end point (that is, the treasure's location), and then it is the problem that the remaining segments intersect with the segment (note that this is a strict intersection), and the final figure plus 1 is the result (because there is a boundary wall), and there is the case when the n=0 needs to be handled specifically.
Personal feeling, the calculation of the simple problem of geometry is the template, just remember that these common templates (cross product, line intersection, Point,line) General computational geometry is no problem.
AC Code:
#include <map> #include <set> #include <list> #include <cmath> #include <queue> #include <stack> #include <vector> #include <cstdio> #include <string> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm>using namespace std;const int inf=0x3f3f3f3f; typedef long Long Ll;typedef unsigned long long ull; #define PrN printf ("\ n") #define SI (n) scanf ("%d",& (n)) #define SII ( N,M) scanf ("%d%d",& (n),& (m)) #define SIII (n,m,k) scanf ("%d%d%d",& (n),& (M),& (K)) #define CLE (A, val) memset (A, (Val), sizeof (a)) #define REP (I,b) for (int. i=0;i< (b); i++) #define REP (i,a,b) for (int i= (a); i<= (b); i+ +) #define REREP (I,A,B) for (int i= (a); i>= (b); i--) const int max_n= 1000+5; const double eps= 1e-9; int sgn (double x) { if (Fabs (x) < EPS) return 0; if (x < 0) return-1; else return 1;} struct point{double x, y; Point () {}, point (double _x,double _y) {x = _x; y = _y; } Point operator-(const point &b) const {return point (X-B.X,Y-B.Y); } double operator ^ (const point &b) const {return x*b.y-y*b.x; } Double operator * (const point &b) Const {return x*b.x + y*b.y; }};struct line{Point S,e; Line () {} line (point _s,point _e) {s = _s; e = _e; }};bool Inter (line L1,line L2) {//This is to judge one step more, whether it is a boundary point, because the traversal is starting from the boundary, so remove the 2 endpoints if (Fabs (l1.s.x-l2.s.x) <eps&&fabs (L1.S.Y-L2.S.Y) <eps| | Fabs (l1.s.x-l2.e.x) <eps&&fabs (l1.s.y-l2.e.y) <eps) return false;
Return Max (l1.s.x,l1.e.x) >= min (l2.s.x,l2.e.x) && max (l2.s.x,l2.e.x) >= min (l1.s.x,l1.e.x ) && Max (l1.s.y,l1.e.y) >= min (l2.s.y,l2.e.y) && max (l2.s.y,l2.e.y) >= min (l1.s.y,l1.e . Y) && sgn ((l2.s-l1.s) ^ (L1.E-L1.S)) *SGN ((l2.e-l1.s) ^ (l1.e-l1.s)) <= 0 && sgn ((L1.S-L2.S) ^ (L2.E-L2.S)) *SGN ((L1.E-L2.S) ^ (L2.E-L2.S)) <= 0;} Double Dist (point A,point b) {return sqrt ((b-a) * (b-a)); Line line[35]; Point Po[65];int n,num,res=inf;double endx,endy;void sol () {if (n==0) {puts ("number of doors = 1"); Return } rep (i,num) {int ans=0; Line Tel (po[i],point (endx,endy)); Rep (j,n) {if (Inter (Tel,line[j])) {ans++; }} res=min (Ans,res); } printf ("Number of doors =%d\n", res+1);} int main () {double x1,y1,x2,y2; SI (n); Rep (i,n) {scanf ("%lf%lf%lf%lf", &X1,&Y1,&X2,&Y2); Po[num++]=point (X1,Y1); Po[num++]=point (X2,Y2); Line[i]=line (Point (X1,y1), point (X2,y2)); } scanf ("%lf%lf", &endx,&endy); Sol (); return 0;}
POJ 1066 Treasure Hunt (computational geometry)