2020第十一届蓝桥杯国赛(决赛)C/C++ B组F题皮亚诺曲线距离题解

2020第十一届蓝桥杯国赛(决赛)C/C++ B组F题皮亚诺曲线距离题解F 皮亚诺曲线距离 问题描述 皮亚诺曲线是一条平面内的曲线 下图给出了皮亚诺曲线的 1 阶情形 它是从左下角出发 经过一个 3 3 的方格中的每一个格子 最终到达右上角的一条曲线 下图给出了皮亚诺曲线的 2 阶情形 它是经过一个 32 32 的方格中的每一个格子的一条曲线 它是将 1 阶曲线的每个方格由 1 阶曲线替换而成 下图给出了皮亚诺曲线的 3 阶情形 它是经过一个 33 33 的方格中的每一个格子的一条曲线 它是将 2 阶曲线的每个方格由 1 阶曲线替换而成 皮亚诺曲

F: 皮亚诺曲线距离

下图给出了皮亚诺曲线的 3 阶情形,它是经过一个 33 × 33 的方格中的每一个格子的一条曲线。它是将 2 阶曲线的每个方格由 1 阶曲线替换而成。
在这里插入图片描述

皮亚诺曲线总是从左下角开始出发,最终到达右上角。

我们将这些格子放到坐标系中,对于 k 阶皮亚诺曲线,左下角的坐标是(0, 0),右上角坐标是 (3k − 1, 3k − 1),右下角坐标是 (3k − 1, 0),左上角坐标是(0, 3k − 1)。

给定 k 阶皮亚诺曲线上的两个点的坐标,请问这两个点之间,如果沿着皮亚诺曲线走,距离是多少?

题解

这道题比赛时看了下感觉很难,而且隔壁做很久都没出来,便果断放弃,下来后看了下其实感觉也不是很难。你可以把问题分解为分别求从左下角的点到第一个点和第二个点的距离,再把距离相减。通过calc函数计算距离,计算时把整幅图看做是由9个较小的方格组成的,看看从左下角的方格到该点所在的方格所需要走几个方格,再乘以每个方格内部曲线的长度,接着递归调用函数再求在小方格中到该点所在更小的方格要走几格,最后把各步求得的结果加起来就好了。至于其中有的小方格方向和1阶的方向不太一样,其实它就是做了个对称变换,你把它变换回去就可以了,可以不用再分别判断。代码不保证完全正确,反正我试了下没发现问题,但我想如果输入的坐标值太大,有可能会超过范围而出错。

#include 
     #include 
     using namespace std; long long calc(long long x,long long y,int level,int type) { 
   //x,y start from 0, total size:3^level*3^level,type=0-3:起点在左下角,左上角,右上角,右下角 if(level==0)return 0; long long int step,base=pow(9,level-1); if(type==1)y=pow(3,level)-1-y; else if(type==2)x=pow(3,level)-1-x,y=pow(3,level)-1-y; else if(type==3)x=pow(3,level)-1-x; if(x<pow(3,level-1)) { 
    if(y<pow(3,level-1)) { 
    step=0*base; step+=calc(x,y,level-1,0); } else if(y<pow(3,level-1)*2) { 
    step=1*base; step+=calc(x,y-pow(3,level-1),level-1,3); } else { 
    step=2*base; step+=calc(x,y-pow(3,level-1)*2,level-1,0); } } else if(x<pow(3,level-1)*2) { 
    if(y<pow(3,level-1)) { 
    step=5*base; step+=calc(x-pow(3,level-1),y,level-1,1); } else if(y<pow(3,level-1)*2) { 
    step=4*base; step+=calc(x-pow(3,level-1),y-pow(3,level-1),level-1,2); } else { 
    step=3*base; step+=calc(x-pow(3,level-1),y-pow(3,level-1)*2,level-1,1); } } else { 
    if(y<pow(3,level-1)) { 
    step=6*base; step+=calc(x-2*pow(3,level-1),y,level-1,0); } else if(y<pow(3,level-1)*2) { 
    step=7*base; step+=calc(x-2*pow(3,level-1),y-pow(3,level-1),level-1,3); } else { 
    step=8*base; step+=calc(x-2*pow(3,level-1),y-pow(3,level-1)*2,level-1,0); } } //cout< 
    
    return step 
    ; 
    } 
    int 
    main 
    ( 
    ) 
    { 
      
    int level 
    ; cin 
    >>level 
    ; 
    long 
    long 
    int x1 
    ,y1 
    ,x2 
    ,y2 
    ; cin 
    >>x1 
    >>y1 
    >>x2 
    >>y2 
    ; 
    long 
    long s1 
    = 
    calc 
    (x1 
    ,y1 
    ,level 
    , 
    0 
    ) 
    ; 
    //cout< 
      
      long 
      long s2 
      = 
      calc 
      (x2 
      ,y2 
      ,level 
      , 
      0 
      ) 
      ; cout 
      <<s2 
      -s1 
      ; 
      return 
      0 
      ; 
      } 
      
   
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/216702.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 上午11:16
下一篇 2026年3月18日 上午11:16


相关推荐

  • ubuntu 挂在smb服务器的方法[通俗易懂]

    很多时候也是需要再ubuntu下挂在另外一台linux设备,下面是通过smb服务进行访问的命令。sudomount-ousername=xxx,password=xxxx//172.16.21.9/file/work_space/smb/

    2022年4月13日
    154
  • CreateCompatibleDC用法

    CreateCompatibleDC用法CreateCompat 假如需要对屏幕进行比较多的 gdi 函数操作 如果每一步操作都直接对屏幕 dc 进行操作 那出现的大多数可能性都是屏幕的闪烁 一个很好的解决方法就是使用内存 dc 将这些操作全部先在内

    2025年11月15日
    3
  • python学员管理系统流程图_python员工管理系统

    python学员管理系统流程图_python员工管理系统学员管理系统#初学者做的很差劲!!!!!defsystem_information():#打印菜单print(‘-‘*20)print(‘[1]添加学员’)print(‘[2]删除学员’)print(‘[3]修改学员信息’)print(‘[4]查询学员信息’)print(‘[5]显示所有学员信息’)print(‘[6]退出系统’)print(‘-‘*20)stu_list=[{‘name’:’TOM’,’ag

    2026年1月31日
    4
  • 软件测试流程设计—黑盒测试用例设计方法「建议收藏」

    软件测试流程设计—黑盒测试用例设计方法「建议收藏」第1章测试用例设计方法测试用例设计方法包括黑盒测试用例设计方法和白盒测试用例设计方法,下面分别进行介绍。1.1黑盒测试用例设计方法黑盒测试用例设计方法包括等价类划分法、边界值分析法、判定表法、因果图法、正交试验法、状态迁移图法、流程分析法、输入域测试法、输出域分析法、异常分析法和错误猜测法等,下面进行详细介绍。1.1.1 等价类划分法1.什么是等价类划分法等价类划分法是一种典型的黑盒测试设计方法。该方法主要针对测试子项进行规格分析,然后获得用例,而不用对系统内部处理进行深..

    2022年6月1日
    33
  • RedisClient 可视化Redis工具下载「建议收藏」

    RedisClient 可视化Redis工具下载「建议收藏」https://github.com/caoxinyu/RedisClient网站下边的文档说明中如果电脑没有JDK,则点redisclient-win32.x86.2.0.exe如果有JDK,若是64位系统则点redisclient-win32.x86_64.2.0.jar32位系统点redisclient-win32.x86.2.0.jar…

    2022年10月12日
    3
  • python获取文件名后缀名_python获取文件名不含后缀名

    python获取文件名后缀名_python获取文件名不含后缀名importosfile_path=”/home/admin/Desktop/test.py”filepath,tempfilename=os.path.split(file_path)filename,extension=os.path.splitext(tempfilename)filepath文件目录filename文件名extension文件扩展名…

    2025年11月18日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号