精华帖 (0) :: 良好帖 (1) :: 灌水帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-05-30
最后修改:2009-05-30
题目如下 #include <iostream> #include <vector> #include <string> #include <cmath> using namespace std; //对角线最大长度(估算) const double MAXDIS = 15000; //代表一个点 class Point{ public: double x,y; Point(double xa,double ya):x(xa),y(ya){} Point(){} }; class Path{ public: double distance; Point pt; }; //代表一条公路 也就是一条线段 class Line{ public: Point start; Point end; Line(Point s,Point e):start(s),end(e){} Line(){} //判断指定的点是否在本线段上 bool onLine(Point pt){ if(fabs((end.y - pt.y) * (start.x - pt.x) - (start.y - pt.y) * (end.x - pt.x)) < 0.000001){ return true; } else{ return false; } } //计算线段到指定点的最短距离 Path shortestDistance(Point pt){ Path path; double s; double d1,d2,d3; double s1,s2,s3; double retval,temp; s1 = (start.x - pt.x) * (start.x - pt.x) + (start.y - pt.y) * (start.y - pt.y); s2 = (end.x - pt.x) * (end.x - pt.x) + (end.y - pt.y) * (end.y - pt.y); s3 = (start.x - end.x) * (start.x - end.x) + (start.y - end.y) * (start.y - end.y); d1 = sqrt(s1); d2 = sqrt(s2); d3 = sqrt(s3); if((d1 + d2) == d3){ path.distance = 0; path.pt = pt; }else if((d1 + d3) == d2){ path.distance = d1; path.pt = start; }else if((d2 + d3) == d1){ path.distance = d2; path.pt = end; }else if((s1 + s3) < s2){ path.distance = d1; path.pt = start; }else if((s2 + s3) < s1){ path.distance = d2; path.pt = end; }else{ temp = (d1 + d2 + d3) / 2; s = sqrt(temp * (temp - d1) * (temp - d2) * (temp - d3)); path.distance = (2 * s) / d3; int k = (end.y - start.y) / (end.x - start.x); path.pt.x= (k * k * start.x + k * (pt.y - start.y) + pt.x)/(k * k+1); path.pt.y=k * (path.pt.x - start.x) + start.y; } return path; } //计算两线段间的焦点 Point calcPoint(Line line){ Point pt(-1,-1); double k1,k2,b1,b2; bool lim1 = false,lim2 = false; if(start.x != end.x){ k1 = (end.y - start.y) / (end.x - start.x); b1 = start.y - k1 * start.x; }else{ lim1 = true; } if(line.start.x != line.end.x){ k2 = (line.end.y - line.start.y) / (line.end.x - line.start.x); b2 = line.start.y - k2 * line.start.x; }else{ lim2 = true; } if(!lim1 && !lim2){ if(k1 != k2){ pt.x = (b2 - b1) / (k1 - k2); pt.y = k1 * pt.x + b1; } }else if(lim1 && !lim2){ pt.x = b2; pt.y = k2 * pt.x + b2; }else if(!lim1 && lim2){ pt.x = b1; pt.y = k1 * pt.x + b1; } if(pt.x < 0 || pt.y < 0 || !onLine(pt) || !line.onLine(pt) ){ pt.x = -1; pt.y = -1; } return pt; } }; //计算最短路径 floyd算法 vector< vector<double> > shortestPath(vector< vector<double> > graph){ vector< vector<double> > path = graph; for(int k = 0;k < graph.size();k++){ for(int i = 0;i < graph.size();i++){ for(int j = 0;j < graph.size();j++){ if(path[i][j] > graph[i][k] + graph[k][j]){ path[i][j] = graph[i][k] + graph[k][j]; } } } } return path; } int main() { int lineCount = 0; cin >> lineCount; vector<Line> lines; //读取各条线段 for(int i = 0;i < lineCount;i++){ Point start,end; cin >> start.x >> start.y >> end.x >> end.y; lines.push_back(Line(start,end)); } vector<Point> points; //计算交点 for(size_t sx = 0; sx < lines.size();sx++){ for(size_t sy = sx;sy < lines.size();sy++){ Point pt = lines[sx].calcPoint(lines[sy]); if(pt.x != -1 && pt.y != -1) points.push_back(pt); } } Point startPt,endPt,calPt; cin >> startPt.x >> startPt.y >> endPt.x >> endPt.y; //将起点放入集合 points.push_back(startPt); double shortest = 15000; //计算离终点最近的那个点的位置 for(size_t index = 0;index < lines.size();index++){ Path path = lines[index].shortestDistance(endPt); if(path.distance < shortest){ shortest = path.distance; calPt = path.pt; } } points.push_back(calPt); vector< vector<double> > matrix(points.size()); size_t ip,jp; //下面两个循环用来 构造邻接矩阵 for(ip = 0;ip < matrix.size();ip++){ vector<double> to(points.size()); for(jp = 0;jp < points.size();jp++){ to[jp] = MAXDIS; } matrix[ip] = to; } for(ip = 0;ip < points.size();ip++){ for(jp = ip;jp < points.size();jp++){ bool onLine = false; vector<Line>::iterator lit = lines.begin(); while(lit != lines.end()){ if((ip != jp) && (*lit).onLine(points[ip]) && (*lit).onLine(points[jp])){ onLine = true; break; } lit++; } if(onLine){ double dx = fabs(points[ip].x - points[jp].x); double dy = fabs(points[ip].y - points[jp].y); double distance = sqrt(dx * dx + dy * dy); matrix[jp][ip] = matrix[ip][jp] = distance; } } } vector< vector<double> > path = shortestPath(matrix); cout.precision(2); cout << path[points.size()-2][points.size()-1] << endl; }
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
浏览 2448 次