At the beginning, the first thought of the average person is to build a graph and find the shortest path. But the thought of this practice, whether it is code length or algorithm complexity, is a waste of time, it is better to choose not to do it, I think there should be a simple approach.
Think about it: when a door from the four walls on the perimeter comes in and moves to the treasure, the minimum number of doors is actually the link between the entrance and the treasure goalLine goes through several points.
The proof is not good, but it is quite simple to say that the idea is a little like the shortest line between two points. Do not take care of small line segments that are in the cross-border manner. Just the line segments originally entered at the beginning, because within the Square range, these line segments can be imagined as infinitely long, there are k straight lines (walls) between the entry points and the treasure points, and you cannot bypass them. You can only walk through them. walking to the left and right will only increase the wall you want to go through, this is the most basic k-way wall that you always need to pass through.
The following is a simple example. You can see that there are always three lines to pass from the door to the treasure.
So the problem becomes that the dot of the peripheral small line segment is connected to the treasure, and the number of points of intersection with the internal line.
Later, I tried to turn it into a small peripheral line segment connecting the endpoint and the treasure, and the number of intersections with the internal line, however, I think this is probably because the data is weak. It seems that I cannot push it down. Which of the following brothers has been deduced seriously? please correct me ..
The following is the code for connecting the terminal with the treasure ..
# Include <iostream>
# Include <vector>
Using namespace std;
Class Point
{
Public:
Point ()
{
X = 0.0f;
Y = 0.0f;
}
Point (double tx, double ty)
{
X = tx;
Y = ty;
}
Double x, y;
};
Class Segment
{
Public:
Segment ()
{
}
Segment (Point p1, Point p2)
{
Point1 = p1;
Point2 = p2;
}
Point point1, point2;
};
// Return (P2-P1) * (p3-p1)
Double CrossProduct (Point p1, Point p2, Point p3)
{
Point vec1 = Point (p2.x-p1.x, p2.y-p1.y );
Point vec2 = Point (p3.x-p1.x, p3.y-p1.y );
Return (vec1.x * vec2.y-vec1.y * vec2.x );
}
Bool SegmentInteract (Segment seg1, Segment seg2)
{
Double d1 = CrossProduct (seg2.point1, seg2.point2, seg1.point1 );
Double d2 = CrossProduct (seg2.point1, seg2.point2, seg1.point2 );
Double d3 = CrossProduct (seg1.point1, seg1.point2, seg2.point1 );
Double d4 = CrossProduct (seg1.point1, seg1.point2, seg2.point2 );
If (d1 * d2 <0 & d3 * d4 <0)
Return true;
Return false;
}
Int main ()
{
Vector <Segment> segVec;
Vector <Point> pointVec;
Int iSegment;
Cin> iSegment;
Double px1, px2, py1, py2;
For (int I = 0; I <iSegment; I ++)
{
Point p1, p2;
Cin> p1.x> p1.y> p2.x> p2.y;
SegVec. push_back (Segment (p1, p2 ));
PointVec. push_back (p1 );
PointVec. push_back (p2 );
}
PointVec. push_back (Point (0, 0 ));
PointVec. push_back (Point (0,100 ));
PointVec. push_back (Point (100,100 ));
PointVec. push_back (Point (100,0 ));
Point goalPoint;
Cin> goalPoint. x> goalPoint. y;
Int MinDoorNumber = 1 <30;
For (vector <Point >:: iterator pointIter = pointVec. begin (); pointIter! = PointVec. end (); pointIter ++)
{
Int iInteractNumber = 0;
For (vector <Segment >:: iterator segIter = segVec. begin (); segIter! = SegVec. end (); segIter ++)
{
If (SegmentInteract (Segment (goalPoint, * pointIter), * segIter ))
{
IInteractNumber ++;
}
}
If (iInteractNumber <MinDoorNumber)
{
MinDoorNumber = iInteractNumber;
}
}
If (MinDoorNumber = 1 <30)
MinDoorNumber = 0;
Cout <"Number of doors =" <MinDoorNumber + 1 <endl;
Return 0;
}
Author: qiul12345