2014
02-14

Line & Circle Maze

A deranged algorithms professor has devised a terrible final exam: he throws his students into a strange maze formed entirely of linear and circular paths, with line segment endpoints and object intersections forming the junctions of the maze. The professor gives his students a map of the maze and a fixed amount of time to find the exit before he floods the maze with xerobiton particles, causing anyone still in the maze to be immediately inverted at the quantum level. Students who escape pass the course; those who don’t are trapped forever in a parallel universe where the grass is blue and the sky is green.
The entrance and the exit are always at a junction as defined above. Knowing that clever ACM programming students will always follow the shortest possible path between two junctions, he chooses the entrance and exit junctions so that the distance that they have to travel is as far as possible. That is, he examines all pairs of junctions that have a path between them, and selects a pair of junctions whose shortest path distance is the longest possible for the maze (which he rebuilds every semester, of course, as the motivation to cheat on this exam is very high).
The joy he derives from quantumly inverting the majority of his students is marred by the tedium of computing the length of the longest of the shortest paths (he needs this to know to decide how much time to put on the clock), so he wants you to write a program to do it for him. He already has a program that generates the mazes, essentially just a random collection of line segments and circles. Your job is to take that collection of line segments and circles, determine the shortest paths between all the distinct pairs of junctions, and report the length of the longest one.

The input to your program is the output of the program that generates his mazes. That program was written by another student, much like yourself, and it meets a few of the professor’s specifications:
1) No endpoint of a line segment will lie on a circle;
2)No line segment will intersect a circle at a tangent;
3) If two circles intersect, they intersect at exactly two distinct points;
4)Every maze contains at least two junctions; that is, a minimum maze is either a single line segment, or two circles that intersect.

There is, however, one bug in the program. (He would like to have it fixed, but unfortunately the student who wrote the code never gave him the source, and is now forever trapped in a parallel universe.) That bug is that the maze is not always entirely connected. There might be line segments or circles, or both, off by themselves that intersect nothing, or even little "submazes" composed of intersecting line segments and circles that as a whole are not connected to the rest of the maze. The professor insists that your solution account for this! The length that you report must be for a path between connected junctions!

Example:
1.2.

3.4.

Detail Description:
Pictrue 1: Line segments only. The large dots are the junction pair
whose shortest path is the longest possible.

Pictrue 2: An example using circles only. Note that in this case there is
also another pair of junctions with the same length longest
possible shortest path.

Pictrue 3: Disconnected components.

Pictrue 4: Now the line segments are connected by a circle, allowing for
a longer shortest path.

An input test case is a collection of line segments and circles. A line segment is specified as "L X1 Y1 X2 Y2" where "L" is a literal character, and (X1,Y1) and (X2,Y2) are the line segment endpoints. A circle is specified by "C X Y R" where "C" is a literal character, (X,Y) is the center of the circle, and R is its radius. All input values are integers, and line segment and circle objects are entirely contained in the first quadrant within the box defined by (0,0) at the lower left and (100,100) at the upper right. Each test case will consist of from 1 to 20 objects, terminated by a line containing only a single asterisk. Following the final test case, a line containing only a single asterisk marks the end of the input.

An input test case is a collection of line segments and circles. A line segment is specified as "L X1 Y1 X2 Y2" where "L" is a literal character, and (X1,Y1) and (X2,Y2) are the line segment endpoints. A circle is specified by "C X Y R" where "C" is a literal character, (X,Y) is the center of the circle, and R is its radius. All input values are integers, and line segment and circle objects are entirely contained in the first quadrant within the box defined by (0,0) at the lower left and (100,100) at the upper right. Each test case will consist of from 1 to 20 objects, terminated by a line containing only a single asterisk. Following the final test case, a line containing only a single asterisk marks the end of the input.

L 10 0 50 40
L 10 4 0 50 0
L 10 1 0 60 1 0
L 0 30 50 30
*
C 25 2 5 25
C 50 2 5 25
C 25 5 0 25
C 50 5 0 25
*
L 0 0 80 80
L 80 1 00 100 80
*
L 0 0 80 80
L 80 1 00 100 80
C 85 8 5 10
*
*

Ca se 1: 68.3
Ca se 2: 78.5
Ca se 3: 113.1
Ca se 4: 140.8

http://acm.hit.edu.cn/hoj/problem/view?id=2706

/*This Code is Submitted by billforum for Problem 2706 at 2012-01-29 19:39:56*/
#include <iostream>
#include <queue>

using namespace std;
int H,W;

struct point{
int x,y;
char c;
int step;
int key;
bool f;
};

point data[105][105][16];

int main(int args,char** argv)
{
char ch;
int sx,sy,ans,flag,t;
int dx[4]={0,-1,0,1};
int dy[4]={-1,0,1,0};
while(cin>>H>>W&&H&&W)
{
ans=0;
flag=0;
for(int i=0;i<H;i++)
for(int j=0;j<W;j++)
{
cin>>ch;

for(int f=0;f<16;f++)
{

data[i][j][f].x=j;
data[i][j][f].y=i;
data[i][j][f].step=0;
data[i][j][f].c=ch;
data[i][j][f].key=f;
data[i][j][f].f=0;
if(ch=='*')
{
sx=j;
sy=i;
}
}
}
queue<point> list;
data[sy][sx][0].f=1;
list.push(data[sy][sx][0]);
while(!list.empty())
{
point tmp=list.front();
if(tmp.c=='X')
{
flag=1;
ans=tmp.step;
break;
}
for(int i=0;i<4;i++)
{
if(tmp.x+dx[i]>=0&&tmp.x+dx[i]<W&&tmp.y+dy[i]>=0&&tmp.y+dy[i]<H)
{
int tx=tmp.x+dx[i];
int ty=tmp.y+dy[i];
int key=tmp.key;
if(data[ty][tx][key].c=='#') continue;
if(data[ty][tx][key].c=='.'||data[ty][tx][key].c=='*'||data[ty][tx][key].c=='X')
{
if(data[ty][tx][key].f==0)
{
data[ty][tx][key].f=1;
data[ty][tx][key].step=tmp.step+1;
list.push(data[ty][tx][key]);
}
continue;
}
//此处写得比较繁琐，这段代码的功能是用于检测字符Y R G B，y r g b；
if(data[ty][tx][key].c=='Y')
{
if((data[ty][tx][key].key&8)!=0)
{
if(data[ty][tx][key].f==0)
{
data[ty][tx][key].f=1;
data[ty][tx][key].step=tmp.step+1;
list.push(data[ty][tx][key]);
}
continue;
}
continue;
}
if(data[ty][tx][key].c=='R')
{
if((data[ty][tx][key].key&4)!=0)
{
if(data[ty][tx][key].f==0)
{
data[ty][tx][key].f=1;
data[ty][tx][key].step=tmp.step+1;
list.push(data[ty][tx][key]);
}
continue;
}
continue;
}
if(data[ty][tx][key].c=='G')
{
if((data[ty][tx][key].key&2)!=0)
{
if(data[ty][tx][key].f==0)
{
data[ty][tx][key].f=1;
data[ty][tx][key].step=tmp.step+1;
list.push(data[ty][tx][key]);
}
continue;
}
continue;
}
if(data[ty][tx][key].c=='B')
{
if((data[ty][tx][key].key&1)!=0)
{
if(data[ty][tx][key].f==0)
{
data[ty][tx][key].f=1;
data[ty][tx][key].step=tmp.step+1;
list.push(data[ty][tx][key]);
}
continue;
}
continue;
}
if(data[ty][tx][key].c=='y')
{
int kk=data[ty][tx][key].key|8;
if(data[ty][tx][kk].f==0)
{
data[ty][tx][kk].f=1;
data[ty][tx][kk].step=tmp.step+1;
list.push(data[ty][tx][kk]);
}
continue;
}
if(data[ty][tx][key].c=='r')
{
int kk=data[ty][tx][key].key|4;
if(data[ty][tx][kk].f==0)
{
data[ty][tx][kk].f=1;
data[ty][tx][kk].step=tmp.step+1;
list.push(data[ty][tx][kk]);
}
continue;
}
if(data[ty][tx][key].c=='g')
{
int kk=data[ty][tx][key].key|2;
if(data[ty][tx][kk].f==0)
{
data[ty][tx][kk].f=1;
data[ty][tx][kk].step=tmp.step+1;
list.push(data[ty][tx][kk]);
}
continue;
}
if(data[ty][tx][key].c=='b')
{
int kk=data[ty][tx][key].key|1;
if(data[ty][tx][kk].f==0)
{
data[ty][tx][kk].f=1;
data[ty][tx][kk].step=tmp.step+1;
list.push(data[ty][tx][kk]);
}
continue;
}
}
}
list.pop();

}
if(flag==1)
cout<<"Escape possible in "<<ans<<" steps."<<endl;
else cout<<"The poor student is trapped!"<<endl;
}

return 0;
}

1. 问题3是不是应该为1/4 .因为截取的三段，无论是否能组成三角形， x， y-x ，1-y,都应大于0，所以 x<y,基础应该是一个大三角形。小三角是大三角的 1/4.

2. “再把所有不和该节点相邻的节点着相同的颜色”，程序中没有进行不和该节点相邻的其他节点是否相邻进行判断。再说求出来的也不一样是颜色数最少的