原文地址:https://luvletter.blog.luogu.org/p1014-ti-jie

P1014 [NOIP1999 普及组] Cantor 表

题目描述

现代数学的著名证明之一是 Georg Cantor 证明了有理数是可枚举的。他是用下面这一张表来证明这一命题的:

1/11/11/1 , 1/21/21/2 , 1/31/31/3 , 1/41/41/4 , 1/51/51/5 , …

2/12/12/1 , 2/22/22/2 , 2/32/32/3 , 2/42/42/4 , …

3/13/13/1 , 3/23/23/2 , 3/33/33/3 , …

4/14/14/1 , 4/24/24/2 …

5/15/15/1 , …

我们以 Z 字形给上表的每一项编号。第一项是,然后是 1/21/21/2,2/12/12/1,3/13/13/1,2/22/22/2,…

输入格式

整数 NNN(1≤N≤1071 \leq N \leq 10^71≤N≤107)。

输出格式

表中的第 NNN 项。

输入输出样例

输入 #1

7

输出 #1

1/4

题解

这一题其实非常简单,不过我一开始做的时候为了方便调试在外面加了一个死循环,后面又忘了删掉了,导致提交结果出现TLE。

刚开始我还以为是我求平方根的算法的问题导致的超时(求平方根用的是从1开始一个一个平方去试的方法,时间复杂度为O(n)O(n)O(n)),所以自己还搞了一个用二分法求平方根的算法(时间复杂度为O(log⁡n)O(\log n)O(logn)),但是还是没有用,后来才发现是之前测试用的循环的问题,把它删掉了就好了。不过也算是给自己多一次练习了。

不过在实际应用中求平方根也不可能用一个一个试的方法,效率太低,所以会用二分法、牛顿法等算法进行优化,其实牛顿法理论上计算的步骤更少,时间复杂度更低(时间复杂度为O(log⁡(log⁡n))O(\log(\log n))O(log(logn))),不过这些都不在一题的考察范围内,所以这里就不再多说了。

在这一题里面,求某一项所在的对角线序数其实可以直接用累加法一个一个加进行实现,但是这样太麻烦,所以可以采用解一元二次方程+求平方根的方法进行简化,不过这里的求平方根算法的时间复杂度最好要低于O(n)O(n)O(n),否则就没有起到简化的作用,失去了求平方根的意义了。解决了这个问题后,后面的问题就十分简单了。

代码(C++):

#include <iostream>using namespace std;//整数平方根函数
unsigned mysqrt(unsigned x)
{//二分法计算平方根unsigned min, max, mid;//计算x的位数unsigned digit = 0;for (unsigned x0 = x;x0 > 0;){x0 >>= 1;digit++;}//确定二分法计算区间的范围,通过求出的位数缩小查找范围if (digit % 2) //位数为奇数{//2^(digit-1) <= x < 2^digit,2^((digit-1)/2) <= √x<2^(digit/2) = √2*2^((digit-1)/2) < 1.5*2^((digit-1)/2)min = 1 << (digit - 1) / 2;max = digit == 1 ? 2 : min / 2 * 3; //digit=1时特殊处理}else //位数为偶数{//2^(digit-1) <= x < 2^digit,1.25*2^(digit/2-1) < √2*2^(digit/2-1) = 2^((digit-1)/2) <= √x<2^(digit/2)max = 1 << digit / 2;min = digit > 4 ? max / 8 * 5 : max / 2; //digit=0,2,4时特殊处理}//二分法求平方根while (max - min > 1){mid = (min + max) / 2;if (mid*mid == x)return mid;else if (mid*mid < x)min = mid;elsemax = mid;}//max-min=1时,直接比较max*max和x的值即可if (max*max == x)return max;elsereturn min;
}int main()
{unsigned n;unsigned a = 0;cin >> n;//计算第n项所在的对角线的序号a//-----------------------------------------------------------------//(这里其实可以直接用累加法进行相加比较计算对角线的序号a,不需要去求平方根)//第a条对角线的第一项在表中的序号为a(a-1)/2+1//n=a(a-1)/2+1//a=[(√(8n-7)+1)/2](a取使a(a-1)/2+1小于等于n的最大值,即上面方程的正数解向下取整后的值)a = mysqrt(n * 8 - 7); //[√(8n-7)]a = (a + 1) / 2; //[(√(8n-7)+1)/2]//-----------------------------------------------------------------//第n项所在的对角线的第一项在表中的序号n0为a(a-1)/2+1unsigned b = n - (a*(a - 1)) / 2; //第n项是所在的对角线的第b项,b=n-n0+1if (a % 2) //对角线序号为奇数cout << a - b + 1 << '/' << b << endl; //表中的第n项为(a-b+1)/belse //对角线序号为偶数cout << b << '/' << a - b + 1 << endl; //表中的第n项为b/(a-b+1)return 0;
}

洛谷P1014题解 [NOIP1999 普及组] Cantor 表相关推荐

  1. 洛谷 P1014 [NOIP1999 普及组] Cantor 表 | OpenJudge NOI 2.1 8760:Cantor表

    [题目链接] 洛谷 P1014 [NOIP1999 普及组] Cantor 表 OpenJudge NOI 2.1 8760:Cantor表 [题目考点] 1. 二维数组 2. 找规律 3. 两下标间 ...

  2. 洛谷——P1014 [NOIP1999 普及组] Cantor 表

    P1014 [NOIP1999 普及组] Cantor 表 题目描述 现代数学的著名证明之一是 Georg Cantor 证明了有理数是可枚举的.他是用下面这一张表来证明这一命题的: 1/11/1 , ...

  3. 洛谷P1014 [NOIP1999 普及组] Cantor 表

    现代数学的著名证明之一是 Georg Cantor 证明了有理数是可枚举的.他是用下面这一张表来证明这一命题的: 代码 import java.util.*; public class Main{pu ...

  4. 洛谷千题详解 | P1014 [NOIP1999 普及组] Cantor 表【C++、Java语言】

    博主主页:Yu·仙笙 专栏地址:洛谷千题详解 目录 题目描述 输入格式 输出格式 输入输出样例 解析: C++源码: C++源码2: C++源码3: Java源码: ----------------- ...

  5. 洛谷 - P1014 [NOIP1999 普及组] Cantor 表 [Java版]

    题目描述 现代数学的著名证明之一是 Georg Cantor 证明了有理数是可枚举的.他是用下面这一张表来证明这一命题的: 1/11/1 , 1/21/2 , 1/31/3 , 1/41/4, 1/5 ...

  6. P1014 [NOIP1999 普及组] Cantor 表

    题目描述 现代数学的著名证明之一是 Georg Cantor 证明了有理数是可枚举的.他是用下面这一张表来证明这一命题的: 1/11/1 , 1/21/2 , 1/31/3 , 1/41/4, 1/5 ...

  7. 洛谷P1035题解 [NOIP2002 普及组] 级数求和

    原文地址:https://luvletter.blog.luogu.org/p1035-ti-jie 题解 本体难度不大,但要注意计算和的时候要使用double类型,千万不能使用float类型,不然会 ...

  8. 洛谷P1055题解 [NOIP2008 普及组] ISBN 号码

    原文地址:https://luvletter.blog.luogu.org/p1055-ti-jie 题解 超级简单的一题,就是要注意输入和输出的分隔符的问题以及ASCII码中0~9这10个数字对应的 ...

  9. 信息学奥赛一本通 1981:【18NOIP普及组】对称二叉树 | 洛谷 P5018【NOIP2018 普及组】 对称二叉树

    [题目链接] ybt 1981:[18NOIP普及组]对称二叉树 洛谷 P5018[NOIP2018 普及组] 对称二叉树 [题目考点] 二叉树 [解题思路] 先求出二叉树中各子树的结点数 遍历二叉树 ...

最新文章

  1. 用sublime server 启动本地服务器(手机访问电脑页面)
  2. Inno Setup制作应用程序安装包
  3. hadoop 3 配置yarn
  4. 忘记手势密码的解决办法
  5. 基础编程题目集 7-4 BCD解密 (10 分)
  6. jQuery最核心的基础设施之一——数据缓存模块进化史
  7. 引入方式之外部样式表(CSS、HTML)
  8. [转载] pandas中Series数组创建方法
  9. ROS与Arduino:ros_arduino_bridge功能包的使用解读
  10. 3Q大战多年后,互联网圈再没有仗义执言的优秀屌丝了
  11. 机械螺旋缠绕法管道非开挖修复
  12. GB28181国标流媒体服务解决方案4G摄像头互联网直播方案EasyGBS云端录像-国标通道录像云端存储查询功能
  13. JAVA中list根据某个字段排序
  14. 使用antV-G6在angualr中画树形关系图
  15. 【BIT2021程设】7. 一夜发白《千字文》——Unicode和UTF-8、位运算
  16. 通过L0phtcrack 7进行账号口令破解
  17. 如何制作Windows98启动盘的方法
  18. win7删除文件夹提示找不到项目,文件删不掉怎么办?
  19. 浅谈:支付结算系统的重要性
  20. 老中医开药,有需要的自己取

热门文章

  1. JVM 并发性: Java 和 Scala 并发性基础(1)
  2. x^(1/x)相关问题极限求解思路
  3. matlab读取wav,播放wav,绘制语音波形图
  4. 浅析SaaS软件和传统软件交付模式的区别
  5. calculate简写_通用简写表
  6. 李兴华java开发实战经典-枚举
  7. xp下报错“不是有效的win32应用程序”
  8. 红月之特装数据(转自官方)
  9. flash读xml实例教程
  10. 电子眼工作原理(防拍)