蓝桥杯 历届试题 荒岛探测-程序员宅基地

技术标签: 笔记  

[蓝桥杯] 历届试题 荒岛探测

这个题目的测试点是有点问题的,毕竟不是第一次遇上这种情况了,个人感觉下面的代码应该可以过,如果真有问题,希望看见的可以在评论区告诉我一下,感激不尽。下面代码过了70%,又是这个数,第三次了,写的三篇蓝桥的全是70%的分,嗯。。。。这数字有毒

题目描述:

科学家小蓝来到了一个荒岛,准备对这个荒岛进行探测考察。

小蓝使用了一个超声定位设备来对自己进行定位。为了使用这个设备,小蓝需要在不同的点分别安装一个固定的发射器和一个固定的接收器。小蓝手中还有一个移动设备。定位设备需要从发射器发射一个信号到移动设备,移动设备收到后马上转发,最后由接收器接收,根据这些设备之间传递的时间差就能计算出移动设备距离发射器和接收器的两个距离,从而实现定位。

小蓝在两个位置已经安装了发射器和接收器,其中发射器安装在坐标( x A x_A xA, y A y_A yA) ,接收器安装在坐标( x B x_B xB, y B y_B yB)。小蓝的发射器和接收器可能在岛上,也可能不在岛上。

小蓝的定位设备设计有些缺陷,当发射器到移动设备的距离加上移动设备到接收器的距离之和大于L 时,定位设备工作不正常。当和小于等于L时,定位设备工作正常。为了安全,小蓝只在定位设备工作正常的区域探测考察。

已知荒岛是一个三角形,三个顶点的坐标分别为 ( x 1 x_1 x1, y 1 y_1 y1),( x 2 x_2 x2, y 2 y_2 y2) ,( x 3 x_3 x3, y 3 y_3 y3) 。

请计算,小蓝在荒岛上可以探测到的面积有多大?

在这里插入图片描述

样例输入

10 6 4 12 12
0 2 13 2 13 15

输出样例

39.99

在这里插入图片描述

解题思路

因为前不久刚好做了一道扫描线的题,所有比较容易想到用扫描线来做。题目的目的是求椭圆与三角行的相交部分的面积,解题大致思路就是用一条平行于y轴的直线设为xi,每次xi+0.001(本来估算+0.01的,不过测试时发现+0.001运行时间也是0毫秒,就干脆提高一点精度了),然后像积分那样将面积分成一个一个小矩形一点一点加起来。计算三角形和椭圆重叠部分面积等价于计算,所有相同xi下三角形里分割出的矩形与椭圆里分割出的矩形重叠面积之和如下图
在这里插入图片描述
所有x1下像图中椭圆浅粉色矩形与三角形灰蓝色重叠部分之和,就是我们要的答案了。
在有解情况下x=xi时,三角形与直线x=xi可以得到两个解y1,y2(y1<=y2),椭圆同理可得y3,y4(y3<=y4),如果min(y2,y4)>max(y1,y3) ,总面积sum就加上(min(y2,y4)-max(y1,y3) )* 0.001 (0.001是所选的精度)。三角形的y1,y2,计算比较简单,算三条直线即可。椭圆就比较麻烦了,毕竟高中只学过焦点所在直线在坐标轴上焦点的中点在坐标原点的,我先试了一下直接解方程

(xi- x A x_A xA)2+(y- y A y_A yA)2)1/2+((xi- x B x_B xB)2+(y- y B y_B yB)2)1/2=L

刚开始以为解这个方程很难就没有去算。。。写着写着博客感觉这就是两个平方的事。。。 觉得下面方法不合适自己的话可以尝试解方程,下面我讲一讲另一种方法:
由于只学过上述的那种椭圆,所以我的想法就是把二维坐标移动到自己想要的位置即可,即以椭圆中心为原点,焦点所在直线为x轴,其他的坐标同时更新,则椭圆方程为x2/a2+y2/b2=1。然后用椭圆准线(x=+a2/c,x=-a2/c)的性质(椭圆上的点到准线的距离比上该点到对应焦点的距离等于离心率a/c) ,再用上勾股定理就可以求对应的y值

代码:

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 1e5+5;
struct point{
    
    double x,y;
    bool operator<(const point& a){
    
        return x<a.x;
    }
    point operator-(const point& a){
    
    	point k;
    	k.x=x-a.x;k.y=y-a.y;
    	return k;
	}
	point(){
    x=0,y=0;}
};
point P1,P2,R[3];
double A[3],B[3],a,b,c;
void Rjd(int a,int b,point &m1,point &m2,double x){
    //求三角形的y1,y2 
	if(fabs(B[a])<1e-6||fabs(B[b])<1e-6){
    
		m1.y=min(R[a].y,R[b].y);
		m2.y=max(R[a].y,R[b].y);
		return;
	}
	m1.y=(1-A[a]*x)/B[a];
	m2.y=(1-A[b]*x)/B[b];
	if(m1.y>m2.y)swap(m1,m2);
}

void TY(double x,point &m1,point &m2){
    //横坐标为x时,求y1,y2  (x+a^2/c)/p=a/c  p是横坐标为x的扫描线与椭圆的交点到椭圆左焦点的距离 y2=sqrt(p^2-(x+c)^2) 
	double p=(x*c/a+a);
	m2.y=sqrt(p*p-(x+c)*(x+c));
	m1.y=-m2.y;
}

int main(){
     //测试数据有问题比如测试点五,用CAD作图得到的答案2279.7457,测试给的答案是2486.14,我的答案与作图答案一致。故只过70%,剩下两个测试点还未验证应该也是答案问题 
    int L;
    cin>>P1.x>>P1.y>>P2.x>>P2.y>>L;
    cin>>R[0].x>>R[0].y>>R[1].x>>R[1].y>>R[2].x>>R[2].y;//处理,重建坐标系,使焦点在x轴 
    
    if(P1.x>P2.x)swap(P1,P2); 
    c=(P1.x-P2.x)*(P1.x-P2.x)+(P1.y-P2.y)*(P1.y-P2.y);
    c=sqrt(c)/2;//半焦距 
	a=L/2; 
    b=sqrt(a*a-c*c);// x^2/a^2+y^2/b^2=1 
    
    double tA1,tB1,tC1=1;//横坐标直线 tA1*x+tB1*y=1 
    tA1=(P2.y-P1.y)/(P1.x*P2.y-P1.y*P2.x);
    tB1=(P1.x-P2.x)/(P1.x*P2.y-P1.y*P2.x);
    point O;//新原点 
    O.x=(P1.x+P2.x)/2;O.y=(P1.y+P2.y)/2;
	for(int i=0;i<3;i++)R[i]=R[i]-O;//更新三角形顶点相对位置 
	P2=P2-O;
	
	double dx=-P2.y;
	double sina=dx/c;//坐标轴逆时针旋转a° 新坐标为 x=Xcosa-Ysina y=Xsina+Ycosa
	double cosa=sqrt(c*c-dx*dx)/c;
	
	P1.x=-c;P1.y=0;
	P2.x=c;P2.y=0;
    for(int i=0;i<3;i++){
    
    	point temp=R[i];
    	R[i].x=temp.x*cosa-temp.y*sina;
    	R[i].y=temp.x*sina+temp.y*cosa;
	}//所有点更新完毕 
    
    sort(R,R+3);

    A[2]=(R[2].y-R[1].y)/(R[1].x*R[2].y-R[1].y*R[2].x);//直线方程A*x+B*y=1; 
    if(fabs(R[1].x-R[2].x)<1e-6)B[2]=0;
    else B[2]=(R[1].x-R[2].x)/(R[1].x*R[2].y-R[1].y*R[2].x);
    A[1]=(R[2].y-R[0].y)/(R[0].x*R[2].y-R[0].y*R[2].x);
    if(fabs(R[2].x-R[0].x)<1e-6)B[1]=0;
    else B[1]=(R[0].x-R[2].x)/(R[0].x*R[2].y-R[0].y*R[2].x);
    A[0]=(R[0].y-R[1].y)/(R[1].x*R[0].y-R[1].y*R[0].x);
    if(fabs(R[1].x-R[0].x)<1e-6)B[0]=0;
    else B[0]=(R[1].x-R[0].x)/(R[1].x*R[0].y-R[1].y*R[0].x); 
	
    double sum=0;
    double l=max(R[0].x,-a),r=min(R[2].x,a);
    for(double i=l;i<r;i+=0.001){
    
    	point m1,m2,m3,m4;
        if(i<R[1].x){
    
            Rjd(0,1,m1,m2,i);
        }else{
    
            Rjd(2,1,m1,m2,i);
        }

		TY(i,m3,m4);
		if(m1.y>m3.y)m3.y=m1.y;
		if(m2.y<m4.y)m4.y=m2.y;
		if(m3.y<m4.y)sum+=(m4.y-m3.y)*0.001;//面积重叠部分相加 
		
    }
    printf("%.2lf\n",sum);
    return 0;
}

以下是在autoCAD上画的图:

测试点三:

没有改变坐标轴时

改变坐标轴时:
在这里插入图片描述

测试样例五:

没改坐标轴时:
在这里插入图片描述
计算面积得2279.7457 而测试答案给的是2486.14,差的有点多,我的运行结果是2279.75,所以感觉应该是答案有问题
改坐标轴后:
在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_48960163/article/details/115124027

智能推荐

mysql xml字段转json格式_mysql将xml数据或者json数据转换为表格。-程序员宅基地

文章浏览阅读131次。我需要将一个xml的数据或者json数据的字符串转化为一个mysql中的表格形式。json_extract函数只能处理单个json数据,无法处理json数组,ExtractValue函数取出来的数据是拼接在一起的,不知道怎么分开,有没有其他办法呢,请教各位大神数据样例:[{"fCategoryId":"796","fCondition":"0.8"},{"fCategoryId":"730","f...

数字电路期末实验报告_module shared(x1,x2,s,f); input x1,x2,s; output f;-程序员宅基地

文章浏览阅读327次。首先在我的电脑选择一个盘打开然后在一个位置创建一个文件夹然后新建一个记事本文档将文件后缀名改为.v然后将实验代码输入到记事本文件中并保存然后打开Quartus II软件新建一个工程在弹出的选择界面中找到刚刚建立的记事本文档,工程名和记事本文档名字一样然后在下一个选择框中同样找到那个文件所在位置,调整相应的状态点击完成然后代码就导入到了工程中在最左侧的方框中右键文件点击setting然后又会弹出一个选择框然后调成modesilm然后调整一系列数据点击OK然后最左侧方框点击files点击文件右_module shared(x1,x2,s,f); input x1,x2,s; output f; assign f = (~s&x1)|(s&x2)

基于51单片机的心率体温检测系统设计_51单片机心率体温测量仪-程序员宅基地

文章浏览阅读1.2k次,点赞29次,收藏24次。摘 要 IAbstract II引 言 11 控制系统设计 21.1 主控系统方案设计 21.2 脉搏传感器方案设计 31.3 系统工作原理 52 硬件设计 62.1 主电路 62.1.1 单片机的选择 62.1.2 STC89C51的主要功能及性能参数 62.1.3 STC89C51单片机引脚说明 62.2 驱动电路 82.2.1 比较器的介绍 82.3放大电路 82.4最小系统 113 软件设计 133.1编程语言的选择 133.2 Keil程序开发环境 _51单片机心率体温测量仪

[IOT]NB模组使用流程_nb-iot工作步骤-程序员宅基地

文章浏览阅读770次,点赞3次,收藏8次。OneNET介绍_nb-iot工作步骤

Android Camera MIPI接口知识总结_csi的带宽估算adc色彩深度-程序员宅基地

文章浏览阅读1.5w次,点赞12次,收藏84次。Android Camera MIPI接口知识总结_csi的带宽估算adc色彩深度

计算机网络原理公式,计算机网络原理公式及计算题-程序员宅基地

文章浏览阅读3.4k次,点赞2次,收藏19次。计算机网络原理公式及计算题 (25页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦!11.90 积分 计算机网络原理公式及计算题第三章物理层公式一:数据传输速率的定义和计算每秒能传输的二进制信息位数,单位为位/秒(bits per second),记作bps或b/s R=1/T*Log2N(bps)T为一个数字脉冲信号的宽度(全宽码情况)或重复周期(归..._计算机网络公式总结

随便推点

2023年美赛C题评委文章及O奖论文解读 - 美国大学生数学建模竞赛 从评委和O奖论文出发-O奖论文_美赛2023c题o奖论文-程序员宅基地

文章浏览阅读2.2k次,点赞31次,收藏36次。每年美赛结束后,评委根据参赛情况撰写评论文章,其中包括:以23年C题为代表的预测模型问题的关键点是什么?对23年C题各个小问的评价:哪些队伍的方案做得好,好在哪里?对文章其他部分的评价:数据预处理、敏感性分析…本文结合评委意见和当年O奖论文对23年美国大学生数学建模竞赛C题做出要点分析和总结,让我们一起来看看2023年美赛C题赛题分析吧!_美赛2023c题o奖论文

绕过cdn-程序员宅基地

文章浏览阅读251次,点赞8次,收藏2次。通过在线工具超级ping,如果结果各地ping ip不太一样,证明使用了cdn。服务器可能会有多个域名,如果它的服务器的子域名可能因为访问量问题而不需要做CDN。这样我们直接nslookup 域名就直接解析出目标真实ip了。和各地ping一个原理,服务器可能在偏僻国家并没有做cdn。以国外的ip请求访问 因为可能对方只做了国内的cdn。查询历史ip域名绑定记录,很可能ip还是和现在一样的。直接ddos对方 消耗掉cdn资源。ico文件的hash值在引擎上搜索。通过邮件原文查看真实ip。

Sublime怎么关闭update更新提醒-程序员宅基地

文章浏览阅读444次。在Sublime的setting里面添加:"update_check": false,保存即可。

微服务链路跟踪_微服务链路追踪-程序员宅基地

文章浏览阅读455次。一、认识微服务跟踪的基础设施1.zipkintwitter开源的分布式跟踪系统,它的主要功能是收集系统的时序数据,从而追踪微服务架构的系统延时等问题。同时,它还提供了一个非常友好的界面,来帮助分析追踪数据。另外,它还有助于分析微服务之间的依赖关系。2.Spring Cloud Sleuth为Spring Cloud提供了分布式跟踪的解决方案。3.微服务跟踪的目的服务之间通过网络进行..._微服务链路追踪

java报错找不到符号_isnull找不到符号-程序员宅基地

文章浏览阅读1.7k次。报错找不到符号,可能原因很多,也许是jdk版本原因,也许是配置原因,等等先查看下以下配置框选中的,应该为勾选状态。如果不是这个原因,再去查找其他可能。_isnull找不到符号

如何在阿里云上部署django网站(2)——使用MySQL数据库_django使用阿里rds mysql数据库-程序员宅基地

文章浏览阅读1.5k次,点赞2次,收藏3次。如果要在阿里云上部署django网站,建议不要使用django自带的sqlite,虽然一时省事,但带来了很多其他的麻烦。建议使用MySQL或者PostgreSQL。由于MySQL比较流行,我就选择了MySQL。安装MySQL在使用MySQL之前,首先需要安装。在ubuntu系统下,输入以下命令:sudo apt-get install mysql-serversudo apt-get isntal_django使用阿里rds mysql数据库