2020年第十一届蓝桥杯国赛—c++B组—试题F:皮亚诺曲线距离

2020年第十一届蓝桥杯国赛—c++B组—试题F:皮亚诺曲线距离这道题我写了一个多小时 还是自己太菜了 两个样例都过了 三阶皮亚诺随便取了两个点 距离也是正确的 如果有大佬找到了我的问题 欢迎指正以下是我的思路思路总体就是求出两个点到原点的距离 然后相减即可那么具体如何求呢 可以发现 当 k gt 1k gt 1k gt 1 的时候 皮亚努曲线图都可以分解为 3 33 33 3 的 k 1k 1k 1 阶皮亚诺曲线块那么假设当前是第 kik iki 阶 那么我们可以求出经过了多少个 ki 1k i 1ki 1 阶块走到了当前坐标所在的 k

在这里插入图片描述在这里插入图片描述在这里插入图片描述

这道题我写了一个多小时,还是自己太菜了,两个样例都过了,三阶皮亚诺随便取了两个点,距离也是正确的,如果有大佬找到了我的问题,欢迎指正

以下是我的思路

思路

总体就是求出两个点到原点的距离,然后相减即可

那么具体如何求呢,可以发现,当 k > 1 k > 1 k>1 的时候,皮亚努曲线图都可以分解为 3 × 3 3 × 3 3×3 k − 1 k – 1 k1 阶皮亚诺曲线块

那么假设当前是第 k i k_i ki 阶,那么我们可以求出经过了多少个 k i − 1 k_i – 1 ki1 阶块走到了当前坐标所在的 k i − 1 k_i – 1 ki1 阶块

只要求出了走过了几个块,那么因为每一个块中距离都是 ( k i − 1 ) ( k i − 1 ) (k_i – 1)(k_i – 1) (ki1)(ki1) 个, 就能求出在当前块之前已经走过了多少个块

然后再递归 k i − 1 k_i – 1 ki1 阶的情况

直到 k = = 1 k == 1 k==1 时,就划归为了一阶皮亚诺曲线到出发点的距离

因为一阶皮亚诺曲线根据进出方向和矩阵方向,有四种不同的情况,经过分析其实可以写一个坐标的变化,将其都变换为某一种情况求解即可

代码

#include  
     #include  
     using namespace std; typedef long long LL; int k; int x1, y1; int x2, y2; // 一阶皮亚诺距离函数  int get_k1(int x,int y) { 
    int dis = 0; if(x == 0) dis = y; if(x == 1) dis = 3 + (2 - y); if(x == 2) dis = 6 + y; return dis; } // 确定其前面几个 k 块 int get_block(int x, int y, int &d) { 
    int sum = 0; if(x == 0 && y == 0) { 
    d = 0; sum = 0; } if(x == 0 && y == 1) { 
    d = 1; sum = 1; } if(x == 0 && y == 2) { 
    d = 0; sum = 2; } if(x == 1 && y == 2){ 
    d = 2; sum = 3; } if(x == 1 && y == 1) { 
    d = 3; sum = 4; } if(x == 1 && y == 0) { 
    d = 2; sum = 5; } if(x == 2 && y == 0) { 
    d = 0; sum = 6; } if(x == 2 && y == 1) { 
    d = 1; sum = 7; } if(x == 2 && y == 2) { 
    d = 0; sum = 8; } return sum; } // 坐标转换. d 是用来确定哪一种情况,详细值参照题目图 void trans(LL &x, LL &y,int d) { 
    if(d == 0) return; if(d == 1) { 
    x = 2 - x; return; } if(d == 2) { 
    y = 2 - y; return; } if(d == 3) { 
    x = 2 - x; y = 2 - y; return; } } // 递归求解 LL get(LL x, LL y, int k,int d) { 
    LL sum = 0; if(k == 1) { 
    trans(x,y,d); sum += get_k1(x,y); return sum; } LL sub = pow(3,k - 1); int tx = x / sub, ty = y / sub; int blocks = get_block(tx,ty,d); sum = blocks * sub * sub; sum += get(x % sub,y % sub,k - 1,d); return sum; } int main() { 
    cin >> k; cin >> x1 >> y1; cin >> x2 >> y2; get(x1,y1,k,0); cout << abs(get(x1,y1,k,0) - get(x2,y2,k,0)) << endl; return 0; } /* 2 3 4 0 0 */ 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

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

(0)
上一篇 2026年3月17日 下午6:36
下一篇 2026年3月17日 下午6:37


相关推荐

  • redis过期策略六种(java的内存回收机制)

    Redis缓存作为提高系统性能最好的方式相信大家对其一定不陌生,各位作为秃头老码农不仅需要掌握Redis的基础用法还得了解Redis的相关原理,比如Redis过期策略和内存淘汰机制。大家都知道,Redis缓存使用的是内存资源,虽然缓存服务器会配置比较高的内存资源,但如果对于Redis中的缓存数据我们不管不顾,内存资源总有耗尽的时候,这时缓存服务器就无法再对外提供服务了。我们要用有限的服务器资源支撑…

    2022年4月17日
    61
  • flink 窗口

    flink 窗口window 一般真实的流都是无界的 怎么处理无界的数据 可以把无限的数据流进行切分 得到有限的数据集进行处理也就是得到有界流窗口就是将无限流切割为有限流的一种方式 它会将流数据分发到有限大小的桶中进行分析窗口类型时间窗口 timewindow 滚动时间窗口 TumblingWind 将数据依据固定的窗口长度对数据进行切分时间对齐 窗口长度固定 没有重叠 每条数据

    2026年3月16日
    1
  • ai小小外卖教程

    ai小小外卖教程

    2026年3月12日
    3
  • undefined reference to ‘main’

    undefined reference to ‘main’

    2021年8月15日
    241
  • Eclipse导入Java项目报错

    Eclipse导入Java项目报错Eclipse 中导入 Java 项目出现 Noprojectsar 原因 这其实是因为项目中缺少了两个文件 classpath 文件和 project 文件 所以 eclipse 找不到你的项目了 解决方案 在 Eclipse 中再新建一个新的项目 项目的类型和名称和导入的项目名一样 然后再新建的项目目录下 找到 classpath 文件和 project 文件 把它们复制到想要导入的项目中 最后就可以成功导入 不会报错了

    2026年3月19日
    1
  • java phantomjs 截图_phantomjs 截图「建议收藏」

    java phantomjs 截图_phantomjs 截图「建议收藏」phantomjs截图,多个setTimeout是为了让页面尽量加载完整/**截图test.js**/varpage=require(‘webpage’).create();page.viewportSize={width:1024,height:600};page.open(‘http://www.2345.com/’,function(status){varbb=…

    2022年7月14日
    25

发表回复

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

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