C++蓝桥杯皮亚诺曲线距离求解

C++蓝桥杯皮亚诺曲线距离求解

  • 一、题目概述
  • 二、解题分析
    • 2.1解题思路
    • 2.2k值范围限制
  • 三、实现代码
  • 四、代码测试
    • 4.1蓝桥杯测试平台
    • 4.2直接传入原始输入的k值
    • 4.3限制k值大小
    • 4.4pow函数求整数高次幂存在误差
    • 4.5满分代码
  • 附录
    • error: ‘long long int y1’ redeclared as different kind of symbol报错
    • C++中int类型与long long类型取值范围

一、题目概述

给定指定阶数的皮亚诺曲线,以及曲线上的两个点的坐标,求解两个点之间的距离,曲线起点坐标规定为(0,0)

一阶皮亚诺曲线如下图:
在这里插入图片描述
k+1阶的皮亚诺曲线是在k阶曲线的基础上,每一个格子由一阶曲线代替而生成。例如二阶曲线如下图:
在这里插入图片描述
三阶曲线如下图:
在这里插入图片描述
k阶曲线的边长为3的k次幂,格子总数为3的2k次幂。无论k取何值,曲线的起点总为左下角,坐标为(0,0),终点为右上角,坐标为(3的2k次幂-1,3的2k次幂-1)

二、解题分析

2.1解题思路

经过初步分析:

  1. 如果直接求解两点间的距离,那么需要求解任意两点间的详细路径,难度很大
  2. 可以将求两点间距离转换为求出到原点的距离然后相减;
  3. k+1阶曲线是在1阶曲线的基础上层层细化网格而成,那么任意一点到原点的距离也可以先从宏观处入手,层层细化求解

一阶曲线按照从起点到终点的行走顺序对网格进行划分,那么可分为1~9个区域,如下图所示:
在这里插入图片描述
任意k阶曲线都可以划分为上图所示的9个区域,例如二阶曲线划分如下图:
在这里插入图片描述

假设k阶曲线上的任意一点,该点到原点的距离=该点到所在区域起点的距离+本区域之前的区域网格数累加和,而该点到所在区域起点的距离又可以转换以所在区域起点为原点的求解到原点距离的问题,因此可以层层递归求解

根据上述解题思路,细化解题步骤如下:

  1. 首先判断出k阶曲线上任意一点(x,y)所在区域,每个区域的边长为3的k-1次幂,因此可以通过对比大小得出判断;
  2. 点到所在区域起点的距离如果要转换为以所在区域起点为原点的点到该原点的距离,就要将区域的起点映射为区域1的起点,即原点该映射不仅仅是平移,可能还要旋转
  3. 以二阶曲线为例,区域2的起点转换为区域1的起点。区域2的起点坐标为(2,3),如果要转换到(0,0),那么就需要进行映射(2-x,y-3),(x,y)为区域2内的点,2-x说明区域2进行了X轴方向的翻转
  4. 本区域之前的区域网格数累加计算较为简单,每个区域的网格数为3的2k-2次幂,例如区域5之前的区域网格数累加,就等于4×3的2k-2次幂。

解题步骤大致如上,读者对皮亚诺曲线随阶数的增加而在形状上层层裂变的过程有一个形象的想象过程,有助于理解解题步骤。

2.2k值范围限制

由于题目中说明k值范围为1~100,而点的坐标的范围为不超过10的18次方,显然3的100次幂超过了10的18次方,同时也超过了C++中long long类型可表示的范围,因此不能直接将k值代入进行求解,而是要先判断出在10的18次方范围内的最大k值,判断代码如下:

void test_k()
{int k=0;long long p1;while(true){p1=pow(3, k);if(p1>=1e18)break;k++;}cout<<k<<endl;cout<<p1<<endl;
}

得出k值最大为38

三、实现代码

代码使用C++实现,如下:

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;int k;
long long x11,y11,x12,y12;long long func01(long long x, long long y, int k)
{if(k == 0) return 0;long long tmp=pow(3, k-1);if(x < tmp && y < tmp) return func01(x, y, k-1);//region1 if(x < tmp && (y >= tmp && y < tmp*2)) return tmp*tmp + func01(tmp-1-x, y-tmp, k-1);//region2if(x < tmp && (y >= tmp*2 && y < tmp*3)) return 2*tmp*tmp + func01(x, y-tmp*2, k-1);//region3if((x >= tmp && x < tmp*2) && y < tmp) return 5*tmp*tmp + func01(x-tmp, tmp-1-y, k-1);//region6if((x >= tmp && x < tmp*2) && (y >= tmp && y < tmp*2)) return 4*tmp*tmp + func01(tmp*2-1-x, tmp*2-1-y, k-1);//region5if((x >= tmp && x < tmp*2) && (y >= tmp*2 && y < tmp*3)) return 3*tmp*tmp + func01(x-tmp, tmp*3-1-y, k-1);//region4if((x >= tmp*2 && x < tmp*3) && y < tmp) return 6*tmp*tmp + func01(x-tmp*2, y, k-1);//region7if((x >= tmp*2 && x < tmp*3) && (y >= tmp && y < tmp*2)) return 7*tmp*tmp + func01(tmp*3-1-x, y-tmp, k-1);//region8if((x >= tmp*2 && x < tmp*3) && (y >= tmp*2 && y < tmp*3)) return 8*tmp*tmp + func01(x-tmp*2, y-tmp*2, k-1);//region9return -1;
}int main()
{cin>>k;cin>>x11>>y11;cin>>x12>>y12;if(k > 38) k=38;cout<<abs(func01(x11,y11,k)-func01(x12,y12,k))<<endl;return 0;
}

此题代码并不长,关键在于解题思路。

四、代码测试

4.1蓝桥杯测试平台

为测试代码正确性,可以在蓝桥杯的刷题平台提交代码,网址为https://www.lanqiao.cn/problems/?first_category_id=1。

皮亚诺曲线距离题目编号为141,如下图所示:
在这里插入图片描述

4.2直接传入原始输入的k值

在蓝桥杯解题平台对代码进行测试,当将k值直接传入递归函数时,可以得到90%的分数,显示10个测试实例中有一个答案错误,如下图所示:
在这里插入图片描述
在本地运行代码,发现确实是因为3的100次方超出了long long类型的范围,导致错误输出。

4.3限制k值大小

对k值大小进行限制,采用了本文第三节中给出的代码,在蓝桥杯平台提交,结果依然显示10个测试实例中有一个答案错误,后将该错误实例的输入数据与输出数据下载到本地,测试数据如下:

kx11x12y11y12
100972800214282722763781912860110024270972800214336621164781912860202693276

正确输出应为191503939959914635。
在本地运行程序,得到的输出为191503939959943987,确实与答案不一致,经过一番检查后发现,是由于pow函数导致的答案错误

4.4pow函数求整数高次幂存在误差

分别使用pow函数求3的k次幂与连续乘积计算3的k次幂测试结果的一致性,代码如下:

void test_pow()
{int k=1;long long p1,p2=1;while(true){p1=pow(3, k);p2*=3;if(p1>=1e18)break;k++;cout<<p1<<','<<p2<<endl;}cout<<k<<endl;cout<<p1<<endl;
}

输出如下图:

在这里插入图片描述
从输出结果分析,当k≥35时,两种方法计算出的3的k次幂出现了不同,且差异会越来越大。通过查找资料得知:pow函数返回的是double类型,在被强制转换为整型时会出现误差

4.5满分代码

因此代码中不再使用pow函数,而是通过连续乘积计算幂,最终代码如下:

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;int k;
long long p[100];
long long x11,y11,x12,y12;long long func01(long long x, long long y, int k)
{if(k == 0) return 0;//long long tmp=pow(3, k-1);long long tmp=p[k-1];if(x < tmp && y < tmp) return func01(x, y, k-1);//region1 if(x < tmp && (y >= tmp && y < tmp*2)) return tmp*tmp + func01(tmp-1-x, y-tmp, k-1);//region2if(x < tmp && (y >= tmp*2 && y < tmp*3)) return 2*tmp*tmp + func01(x, y-tmp*2, k-1);//region3if((x >= tmp && x < tmp*2) && y < tmp) return 5*tmp*tmp + func01(x-tmp, tmp-1-y, k-1);//region6if((x >= tmp && x < tmp*2) && (y >= tmp && y < tmp*2)) return 4*tmp*tmp + func01(tmp*2-1-x, tmp*2-1-y, k-1);//region5if((x >= tmp && x < tmp*2) && (y >= tmp*2 && y < tmp*3)) return 3*tmp*tmp + func01(x-tmp, tmp*3-1-y, k-1);//region4if((x >= tmp*2 && x < tmp*3) && y < tmp) return 6*tmp*tmp + func01(x-tmp*2, y, k-1);//region7if((x >= tmp*2 && x < tmp*3) && (y >= tmp && y < tmp*2)) return 7*tmp*tmp + func01(tmp*3-1-x, y-tmp, k-1);//region8if((x >= tmp*2 && x < tmp*3) && (y >= tmp*2 && y < tmp*3)) return 8*tmp*tmp + func01(x-tmp*2, y-tmp*2, k-1);//region9return -1;
}int main()
{cin>>k;cin>>x11>>y11;cin>>x12>>y12;if(k > 38) k=38;p[0]=1;for(int i = 1; i <= k; i++) p[i]=p[i-1]*3;cout<<abs(func01(x11,y11,k)-func01(x12,y12,k))<<endl;return 0;
}

上述代码提交后,全部10个用例全部跑通。
在这里插入图片描述

附录

error: ‘long long int y1’ redeclared as different kind of symbol报错

初始编写上述代码时,第一个点的坐标变量本来定义为x1,y1,代码在本地Dev-C++编译器上能够正确运行,但是在蓝桥杯解题平台上运行就报出该错误,后经查找资料后发现,cmath头文件中定义了与y1同名的函数,所以导致报错,因此上述代码中的变量名改为x11,y11,x12,y12。

C++中int类型与long long类型取值范围

类型专用存储空间表示范围次方表示
int4个字节-2,147,483,648~2,147,483,647 − 2 31 -2 ^{31} 231 ~ 2 31 2 ^{31} 231-1,约为10的9次方
unsigned int4个字节0~4,294,967,2950 ~ 2 32 2 ^{32} 232-1,约为10的9次方
long4个字节-2,147,483,648~2,147,483,647 − 2 31 -2 ^{31} 231 ~ 2 31 2 ^{31} 231-1,约为10的9次方
unsigned long4个字节0~4,294,967,2950 ~ 2 32 2 ^{32} 232-1,约为10的9次方
long long8个字节-9,223,372,036,854,775,808~9,223,372,036,854,775,807 − 2 63 -2 ^{63} 263 ~ 2 63 2 ^{63} 263-1,约为10的18次方
unsigned long long8个字节0~18,446,744,073,709,551,6150 ~ 2 64 2 ^{64} 264-1,约为10的19次方

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/31791.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uni-app+vue3学习随笔

目录相关 static文件 编译器会把static目录中的内容整体复制到最终编译包内&#xff0c; 非 static 目录下的文件&#xff08;vue组件、js、css 等&#xff09;只有被引用时&#xff0c;才会被打包编译。 css、less/scss 等资源不要放在 static 目录下&#xff0c;建议这些…

为什么大模型网站使用 SSE 而不是 WebSocket?

在大模型网站&#xff08;如 ChatGPT、Claude、Gemini 等&#xff09;中&#xff0c;前端通常使用 EventSource&#xff08;Server-Sent Events, SSE&#xff09; 来与后端对接&#xff0c;而不是 WebSocket。这是因为 SSE 更适合类似流式文本生成的场景。下面我们详细对比 SSE…

【2025】基于python+django的考研自习室预约系统(源码、万字文档、图文修改、调试答疑)

考研自习室预约系统通过 Python Django 技术栈的深度整合&#xff0c;为考研学生和自习室管理者打造了一个高效、便捷、智能的自习室预约管理平台。系统不仅满足了学生便捷预约自习室的需求&#xff0c;提升了备考效率&#xff0c;还帮助管理者实现了自习室资源的科学管理和优…

Flutter中stream学习

Flutter中stream学习 概述Stream的基础概念stream的常用方法Stream.fromFuture(Future<T> future)Stream.fromFutures(Iterable<Future<T>> futures)Stream.fromIterable(Iterable<T> elements)Stream.periodic(Duration period, [T computation(int c…

计算机网络:计算机网络的组成和功能

计算机网络的组成&#xff1a; 计算机网络的工作方式&#xff1a; 计算机网络的逻辑功能; 总结&#xff1a; 计算机网络的功能&#xff1a; 1.数据通信 2.资源共享 3.分布式处理:计算机网络的分布式处理是指将计算任务分散到网络中的多个节点&#xff08;计算机或设备&…

【redis】五种数据类型和编码方式

文章目录 五种数据类型编码方式stringhashlistsetzset查询内部编码 五种数据类型 字符串&#xff1a;Java 中的 String哈希&#xff1a;Java 中的 HashMap列表&#xff1a;Java 中的 List集合&#xff1a;Java 中的 Set有序集合&#xff1a;除了存 member 之外&#xff0c;还有…

AI与现有运维管理软件之间的相互影响和协同发展

AI与现有运维软件之间的相互影响和协同发展。我们可以从几个角度来探讨&#xff1a; 1. AI与运维软件的共生关系 已有运维软件作为大模型的一部分&#xff1a;运维软件&#xff08;如监控易&#xff09;在长期运行中积累了大量的数据和经验&#xff0c;这些数据和经验可以被用来…

深度评测DeepSeek、ChatGPT O1和谷歌Gemini AI应用开发场景 - DeepSeek性能完胜!

下面我会展示我为期一周的实验结果&#xff0c;创作不宜&#xff0c;希望大家关注我&#xff0c;以后多多互3&#xff01;前一阵我在互联网上看到很多关于DeepSeek R1的讨论&#xff0c;这个开源模型据说可以媲美&#xff0c;甚至优于像OpenAI o1这样的付费模型。 由于我在日常…

使用DeepSeek+蓝耘快速设计网页简易版《我的世界》小游戏

前言&#xff1a;如今&#xff0c;借助先进的人工智能模型与便捷的云平台&#xff0c;即便是新手开发者&#xff0c;也能开启创意游戏的设计之旅。DeepSeek 作为前沿的人工智能模型&#xff0c;具备强大的功能与潜力&#xff0c;而蓝耘智算云平台则为其提供了稳定高效的运行环境…

Hcaptcha验证码自动识别方案详解

Hcaptcha验证系统简介 这个令人头疼的验证系统长这样: 还有这样: 看着就让人不开心,每次都要玩这种小游戏。 工作原理 1. 环境评估(形式主义阶段) 它会检查这些东西: 浏览器指纹行为数据IP地址网站设置 如果你看起来像个"正常访客",它可能就放你过。但要是发现…

SpringBoot事务管理

Spring事务管理 在日常开发过程中&#xff0c;只要涉及数据操作&#xff0c;都不可避免地会涉及事务管理相关内容&#xff0c;而Spring提供了强大的事务管理机制&#xff0c;能够帮助开发者更轻松地处理数据一致性和事务的问题。 一、什么是事务管理 事务&#xff08;Transa…

JU TPS研究笔记

这个模板的Cover Demo和尘白禁区一样&#xff0c;是自由观察和背后锁定视角可切换的TPS。这种模式比单独做自由观察或背后锁定都要复杂。在非瞄准也就是自由观察状态&#xff0c;鼠标控制相机转动&#xff0c;WASD控制人物以相机前方为前方一边移动一边平滑旋转到面对移动方向。…

[NewStarCTF 2023 公开赛道]ez_sql1 【sqlmap使用/大小写绕过】

题目&#xff1a; 发现id处可以sql注入&#xff1a; 虽然输入id1;show databases;#没什么回显&#xff0c;但是知道这里是字符型注入了 这次利用sqlmap注入 --dbs&#xff1a;列出所有数据库名字 python .\sqlmap.py -u http://a40b2f0a-823f-4c99-b43c-08b94ed0abb2.node5.…

DeepSeek-实用集成大礼包

随着DeepSeek的持续火热,在各种平台看到大家基于deepseek+各类应用的案例。这些案例真假难辨,现在DeepSeek已经推出了官方的Awesome DeepSeek Integrations,集成了各类应用,下面是详细的介绍。 DeepSeek Integrations 是 DeepSeek 官方在 GitHub 上精心整理的一个集合了各种…

Ubuntu安装问题汇总

参考文章&#xff1a; 【Ubuntu常用快捷键总结】 【王道Python常用软件安装指引】 1. 无法连接虚拟设备 sat0:0 【问题】&#xff1a;出现下图所示弹框。 【问题解决】&#xff1a; 点击 “否” 。 点击左上角的 “虚拟机” → “设置…” → “CD/DVD (SATA)” &#xff0c;…

深陷帕金森困境,怎样重燃生活信心?

帕金森&#xff0c;这个悄然影响无数中老年人生活的神经系统疾病&#xff0c;正逐渐走进大众视野。患病后&#xff0c;患者常出现静止性震颤&#xff0c;安静时手部、下肢不自主抖动&#xff0c;如同在默默诉说着身体的异常。肢体变得僵硬&#xff0c;行动迟缓&#xff0c;起步…

空间遥感智能处理技术发展现状与趋势

在数字化时代&#xff0c;空间遥感技术已经成为获取地球表面信息的重要手段。随着卫星遥感技术的快速发展&#xff0c;获取的遥感数据量激增&#xff0c;这对遥感数据的智能处理提出了更高的要求。本文将探讨空间遥感智能处理技术的发展现状与未来趋势。 发展现状 大数据与人工…

svn删除所有隐藏.svn文件,文件夹脱离svn控制

新建一个文件&#xff0c;取名remove-svn-folders.reg&#xff0c;输入如下内容&#xff1a; Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN] "Delete SVN Folders" [HKEY_LOCAL_MACHINE\SOFTWARE\Class…

Datawhale coze-ai-assistant 笔记2

目录 快速搭建一个 AI 助手智能体 搭建步骤 步骤1&#xff1a;创建一个智能体 步骤2&#xff1a;编写提示词 步骤3&#xff1a;调试智能体 步骤4&#xff1a;发布智能体 设置智能体模型 选择模型 生成多样性 输入及输出设置 如何使用 步骤1&#xff1a;更换模型 步…

win10电脑鼠标速度突然变的很慢?

电脑鼠标突然变很慢&#xff0c;杀毒检测后没问题&#xff0c;鼠标设置也没变&#xff0c;最后发现可能是误触鼠标的“DPI”调节键。 DPI调节键在鼠标滚轮下方&#xff0c;再次点击即可恢复正常鼠标速度。 如果有和-的按键&#xff0c;速度变快&#xff0c;-速度变慢。 图源&…