`
springfield
  • 浏览: 8225 次
  • 性别: Icon_minigender_1
  • 来自: 未知
最近访客 更多访客>>
社区版块
存档分类
最新评论

百度之星算法题目,高手们都来讨论吧,附上我的解答

阅读更多

题目如下

1. 好心的出租车司机
北京的一位出租车司机向你抱怨:城市发展太快,公路越来越多,他已经疲于计算行驶路线,于是求你开发一个自动导航的工具。
出租车只能在公路上行驶。所有的公路都是笔直、双向的,相交的公路视为连通(可以在交叉点处从一条公路开到另一公路上)。由于道路施工,整个城市的公路系统可能并不完全通畅。如果乘客的目的地不在公路边,则乘客下车后要步行前往,步行路线不受公路限制。这位好心的司机还特别提出,乘客步行距离越短越好;其次,出租车行驶里程越短越好。
方便起见,用笛卡儿坐标系来描述城市地图,所有坐标都在第一象限[0, 10000]的范围内。公路宽度忽略不计。
输入格式
第一行是一个正整数k,代表公路条数。以下k行每行用4个非负整数描述一条公路(用空格隔开),前两个表示公路起点的坐标,后两个表示公路终点的坐标。下一行包含4个非负整数(用空格隔开),前两个表示乘客出发点(保证在某条公路上),后两个表示乘客目的地坐标。乘客必须在出发点上车,中途不换车。任意两条公路最多只有一个公共点。
输出格式
仅一行,为出租车行驶的里程数,保留一位小数(四舍五入)。
输入样例 例


2
2 2 10 10
10 2 2 10
3 3 9 4
输出样例 例
7.8
评分规则
1. 程序将运行在一台Linux机器上(内存使用不作严格限制),在每一测试用例上运行不能超过1秒,否则该用例不得分;
2. 要求程序能按照输入样例的格式读取标准输入数据,按照输出样例的格式将运行结果输出到标准输出上。如果不能正确读入数据和输出数据,该题将不得分;
3. 本题包含20个测试点,前10组满足k<=10,后10组满足k<=50。每个测试点10分,共200分。

下面是我的解答:
   思路如下,首先输入的公路数据可以看成若干条线段,然后可以求出这些线段的交点,后面还有起点和终点坐标,起点坐标一定在这些线段上,所以可以将起点坐标点和这些线段的交点构成一个图,接下来就是终点坐标,由于终点坐标不一定在这些线段上,如果不在的话可以求出终点坐标到这些线段最短距离的那个点,然后将那个点也构建到图中,这样原问题就变成了求起点和刚才那个点最短路径的问题。这是我的思路,附上代码,高手们检查下有没有问题

#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;
}

 

分享到:
评论

相关推荐

    scratch少儿编程逻辑思维游戏源码-拽猫跳跃.zip

    scratch少儿编程逻辑思维游戏源码-拽猫跳跃.zip

    scratch少儿编程逻辑思维游戏源码-足球冠军.zip

    scratch少儿编程逻辑思维游戏源码-足球冠军.zip

    病灶分类粒子群算法优化SVM病灶分类【含Matlab源码 1520期】.md

    机器人开发教程&案例&相关项目资源,奖励仅

    实训商业源码-【原创】Scode源码站原创个人单页-毕业设计.zip

    实训商业源码-【原创】Scode源码站原创个人单页-毕业设计.zip

    实训商业源码-【超人】商家联盟V3.3.0原版免授权-毕业设计.zip

    实训商业源码-【超人】商家联盟V3.3.0原版免授权-毕业设计.zip

    基于STM32的高效步进电机控制算法:SpTA与S型曲线的比较与应用

    内容概要:本文详细介绍了基于STM32的步进电机S型曲线和SpTA加减速控制算法。S型曲线算法通过设定启动频率、加速时间、最高速度和加加速频率等参数,实现平滑的加减速控制,适用于高精度控制场合。SpTA算法则以其良好的自适应性和多路电机控制能力著称,尤其适合CPLD/FPGA环境。文中提供了详细的伪代码和实际代码示例,展示了两种算法的具体实现方法和技术细节。此外,文章还讨论了两种算法的实际测试效果和优化技巧,如利用定时器和DMA提高性能,确保电机运行更加稳定和平滑。 适合人群:从事嵌入式系统开发、步进电机控制及相关领域的工程师和技术爱好者。 使用场景及目标:①需要对步进电机进行高效、稳定的加减速控制;②希望深入了解S型曲线和SpTA算法的工作原理及其实现方法;③寻求优化现有控制系统性能的技术方案。 其他说明:文章不仅提供了理论解释,还包括了大量的代码片段和实际测试数据,帮助读者更好地理解和应用这些算法。

    车牌识别APP模板匹配车牌识别(桂贵京粤苏渝)【含Matlab源码 217期】.md

    计算机二级考试试题&参考资料&心得攻略等资源,

    scratch少儿编程逻辑思维游戏源码-钟声.zip

    scratch少儿编程逻辑思维游戏源码-钟声.zip

    scratch少儿编程逻辑思维游戏源码-宇宙混沌.zip

    scratch少儿编程逻辑思维游戏源码-宇宙混沌.zip

    基于几何相位与补偿相位模型的宽带消色差超构透镜设计与实现——以PR Applied论文为例

    内容概要:本文详细介绍了宽带消色差超构透镜的设计与仿真实现,重点探讨了几何相位和补偿相位的协同作用。通过硅纳米柱结构参数的优化,实现了3.7-4.5μm中红外波段的高效聚焦。文中提供了详细的FDTD建模、Matlab相位计算以及Python优化算法的代码片段,展示了如何通过相位叠加模型解决色散问题。实验结果显示,相比单一几何相位设计,色散补偿效果提升了近3倍,聚焦效率达到了68%。 适合人群:从事光学设计、超构材料研究、电磁仿真领域的科研人员和技术开发者。 使用场景及目标:适用于希望深入了解超构透镜设计原理的研究人员,特别是那些关注宽带消色差性能提升的人群。目标是掌握几何相位与补偿相位的联合应用,提高超构透镜在特定波段的聚焦效率。 其他说明:文章不仅提供了理论推导和公式解释,还分享了许多实际操作中的经验和技巧,如参数扫描、优化算法选择、仿真工具配置等。此外,还讨论了波长泛化能力和常见问题的解决方案。

    【vue】Vue3+TS+Vite+pinia+elementPlus电商项目实战.zip

    【vue】Vue3+TS+Vite+pinia+elementPlus电商项目实战.zip

    scratch少儿编程逻辑思维游戏源码-下落忍者.zip

    scratch少儿编程逻辑思维游戏源码-下落忍者.zip

    西门子1200 PLC轴运动控制程序:成熟应用于装路由器壳子的机器,涵盖伺服与电缸控制及PUT GET通讯块,可复用轴控制与报警块,助力西门子轴控制项目学习与实践

    内容概要:本文详细介绍了基于西门子1200 PLC的轴运动控制在海康威视路由器壳子装配机项目中的应用。主要内容涵盖硬件配置、轴控制程序、气缸报警块、PUT/GET块通讯等多个方面。硬件上,使用西门子1200 PLC为核心控制器,控制3个伺服和1个电缸,并与其他PLC通信。软件层面,通过编写轴控制块、气缸报警块和通讯程序实现了对设备的精确控制。文章不仅展示了具体的代码示例,还分享了许多实战经验和优化技巧,如参数动态加载、通讯超时保护、状态机模式报警处理等。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是对西门子1200 PLC轴运动控制感兴趣的读者。 使用场景及目标:①学习如何使用西门子1200 PLC进行轴运动控制;②掌握轴控制块、气缸报警块和通讯程序的具体实现;③了解工业自动化项目中的常见问题及其解决方案。 其他说明:文章提供了丰富的实战经验和优化技巧,有助于提高读者在实际项目中的开发效率和解决问题的能力。此外,附带的代码示例和详细的注释使得学习更加直观和易懂。

    scratch少儿编程逻辑思维游戏源码-纸片马里奥 激流勇进.zip

    scratch少儿编程逻辑思维游戏源码-纸片马里奥 激流勇进.zip

    XK7130数控铣床工作台及床身设计.rar

    XK7130数控铣床工作台及床身设计.rar

    基于最优线性二次型理论的多智能体系统带外部干扰的最优控制问题研究

    内容概要:本文详细探讨了基于最优线性二次型(LQR)理论的多智能体系统最优控制问题,特别是针对存在外部干扰的情况。文章首先介绍了在无外部干扰条件下,通过性能指标函数优化获得最优分布式控制协议,并展示了具体的Python代码实现。接着,为了应对外部干扰,引入了DOBC(基于干扰观测器的控制)方法,通过估计并补偿干扰,确保系统的稳定性。此外,还提出了带有最小采样粒度的事件触发机制,进一步提高了控制效率,减少了计算资源的消耗。最终,通过仿真验证了所提出方法的有效性和优越性。 适合人群:对多智能体系统、最优控制理论以及相关应用感兴趣的科研人员和技术开发者。 使用场景及目标:适用于需要处理复杂环境下多智能体协作任务的研究项目,如机器人集群控制、自动化系统管理等。主要目标是在存在外部干扰的情况下,实现高效稳定的多智能体系统控制。 其他说明:文中提供了详细的代码示例,帮助读者更好地理解和实现所讨论的技术细节。同时,强调了在实际应用中需要注意的问题,如干扰估计的收敛速度、事件触发条件的设计等。

    MATLAB代码实现电气热综合能源系统耦合优化调度模型及仿真平台分析

    内容概要:本文详细介绍了利用MATLAB及其工具箱YALMIP和求解器CPLEX/Gurobi构建电-气-热综合能源系统的耦合优化调度模型。该模型采用39节点电力系统、比利时20节点天然气系统以及热网系统进行建模,通过直流潮流、线性化处理等手段将复杂的非线性问题转化为线性规划问题,从而提高求解效率。文中展示了具体的数学公式、代码片段及求解策略,如目标函数的设计、气网平衡方程的处理、热电联产(CHP)和电转气(P2G)设备的约束条件等。此外,还讨论了求解器的选择与性能比较,以及模块化的代码设计思想。 适合人群:从事能源系统优化研究的专业人士,尤其是对电力系统、天然气系统和热网系统有深入了解的研究人员和技术人员。 使用场景及目标:适用于希望深入理解电-气-热综合能源系统耦合机制的研究者和技术开发者。主要目标是掌握如何通过MATLAB实现高效的多能耦合优化调度,探索不同能源系统之间的相互作用及其对整体系统性能的影响。 其他说明:文章不仅提供了详细的理论推导和代码实现,还分享了许多实践经验,如参数调优、线性化处理技巧等。这对于实际工程项目中的应用具有重要的指导意义。

    scratch少儿编程逻辑思维游戏源码-月影——城市素材.zip

    scratch少儿编程逻辑思维游戏源码-月影——城市素材.zip

    实训商业源码- CCIA投票小程序V1.1.9开源版 前端+后端-毕业设计.zip

    实训商业源码- CCIA投票小程序V1.1.9开源版 前端+后端-毕业设计.zip

    实训商业源码- 活动报名V4.4.9+年卡插件V1.1.8+分销海报V1.1.2-毕业设计.zip

    实训商业源码- 活动报名V4.4.9+年卡插件V1.1.8+分销海报V1.1.2-毕业设计.zip

Global site tag (gtag.js) - Google Analytics