前些日子在网上发现一道编程题目,引用如下:

题目详情:

本题的奖品由亿阳信通赞助,以下是题目详情:

给定表达式[x/2] + y + x * y, 其中x,y都是正整数。其中的中括号表示下取整,例如[3/2] = 1 , [5/2]  = 2。

有些正整数可以用上述表达式表达出来,例如正整数2,当取x = y = 1时,可以把2表达出来

( 解释下:当x=y=1时, [x / 2] + y + x * y = [1 / 2] + 1 + 1 * 1 = 0+1+1 = 2 );

有些数可以有多种方式表达,例如13可以由 x = 2 y = 4 以及x = 3 y = 3来表示;

有些数无法用这个表达式表达出来,比如3。

从1开始第n个不能用这个表达式表示出来的数,我们叫做an,例如a1=1 a2=3,给定n,求an。

输入:n值 1<=n<=40

输出:an % 1000000007的结果(因为结果较大,输出an %1000000007的结果)。

函数头部

C/C++:

int givean(int n);

java:

public class Main {

public static int givean(int n) {

}

}

答题说明:

main函数可以不用完成,完成givean函数即可,givean函数外可编写其它函数。

=================================================================================================

一时兴起,就尝试解答此题,思路:使用二重循环穷举法来判断一个数是不是不可表示的数。

我的代码:

    public static int givean(int n){if (n < 1 || n > 40){return -1;}long i = 0;while (n > 0){i++;if (isUndisplayNumber(i)){n--;}}return (int) (i % 1000000007);}/*** 判断n是否为不可表示数* * @param n* @return*/private static boolean isUndisplayNumber(long n){if (n == 1 || n == 3){return true;} else if (n % 2 == 0){return false;}for (long i = 1; i <= n; i++){for (long j = 1; j <= n; j++){long m = i / 2 + j + i * j;if (m > n){break;}if (m == n){return false;}}}return true;}

编译和测试结果显示正常(其实givean(6)运行已经超时,超过100s),提交结果:

【抱歉,处理您的请求时出错。】
知道这是因为我的穷举法太费时了,尝试了几种优化方案,但效果都不明显。在此标记,以备后学!

=========================================================================================================================

备注:

后来利用搜索引擎在开心问答网上搜到一篇相关文章(http://www.kaixinwenda.com/article-lzc52151-9957839.html),分析如下:

推导:

1、  对[x/2] + y + x * y分析,试探:x=1,原式=2y,表示所有偶数,即对所有偶数都能用此式表示,故后文重点讨论哪些奇数不能被其表示(本文讨论的所有奇偶数都为非负数)。

2、  对x分为4n,4n+1,4n+2,4n+3四种情况讨论。

容易得到,x=4n+1时,不论y取何值,原式必为偶数,与1)中情况重复,故舍去不讨论;

x=4n时,y=2m+1才能保证原式为奇数,其中要保证n>0;

x=4n+2时,y=2m才能保证原式为奇数,其中要保证m>0;

x=4n+3时,y=2m或2m+1都能使原式为奇数;

故只讨论后三种情况。

3、  把x=4n,y=2m+1代入原式易得2(m+n)+8mn+4n+1、n>0;

把x=4n+2,y=2m代入原式易得2(m+n)+8mn+4m+1、m>0;

明显,这两种情况可表示的奇数是相同的,故只需研究其中一种即可。

总结一下,目前已知原式对所有偶数可表示,对哪些奇数可表示呢?我们要研究的情况只有两种x=4n+2(即x=4n)与x=4n+3时的情况。

4、  对x=4n+2时,不限制y的奇偶性,此情况下,原式可表示为2n+3y+4ny+1;

对x=4n+3时,不限制y的奇偶性,,此情况下,原式可表示为2n+4y+4ny+1;

下面我们重点讨论这两种情况表示的奇数包括哪些。

5、  对x=4n+3,原式=2n+4y+4ny+1=2(n+1)(2y+1)-1,即表示一个奇数(2y+1)的偶数倍减1。也就是说x=4n+3情况时,表示的奇数都具备一个特征:这个奇数可以写成一个奇数的偶数倍减1。

故我们可以得到下面的结论:在x=4n+3的情况下,如果偶数B能写成一个奇数的偶数倍,即奇数与偶数的乘积,那么奇数A=B-1可以被原式表示。

其逆否命题:在x=4n+3的情况下,奇数A=B-1不可以被原式表示,则偶数B不能写成奇数与偶数的乘积,即其因子分解只能写成偶数与偶数的乘积。

一个偶数因子分解只能写成偶数与偶数,只有2的幂了。

故得到结论:在x=4n+3的情况下,不可以被原式表示的奇数都是2的幂减1。

6、  对x=4n+2,原式=2n+3y+4ny+1=[(4n+3)(2m+1)-1]/2,即表示两个奇数的积减1的差的一半。也就是说x=4n+2情况时,表示的奇数都具备一个特征:这个奇数可以写成两个奇数的积(4n+3)(2m+1)减1的差的一半。

换句话说,在x=4n+2的情况下,原式所能表示的奇数A都可以写成两个奇数的积减1的差的一半。反过来,2A+1必定能写成两个奇数的积。

而对任意的2A+1必为奇数,它要么能写成两个奇数的积要么是素数。

故得到结论:在x=4n+2的情况下,不可以被原式表示的奇数A都是某个素数减1的差的一半。

7、  把1)、5)与6)的结论综合起来,对任意正整数x、y,如果不能被原式表示,它必定是奇数,这个奇数必定是2的幂减1,同时是某个素数减1的差的一半。

用形式化语言表达,对任意正整数x、y,不能被[x/2] + y + x * y表示的数,必定可以写成2^p-1,且2^(p+1)-1是一个素数。

8、  于是我们得到这个问题的解答:an中的元素都满足2^p-1且2^(p+1)-1是素数。

--------------------------------------------------------------------------------------

编程求解:

问题从数学上已经解决了,并得到了一个漂亮的解答。但如何求2^p-1,还要判断2^(p+1)-1是否为素数,这都是非常困难。

一步步来,求素数,传统方法当然是素性检测,以前写过一个拉宾米勒测试,很复杂。但突然意识到对2^p-1如果是素数的话,数论被叫做梅森素数,前人肯定有总结。

百度一下,前40个梅森素数的幂指数(p+1)取值为:2,3,5,7,13,17,19,31,61,89,107,127,521,607,1279,2203,2281,3217,4253,4423,9689,9941,11213,19937,21701,23209,44497,86243,110503,132049,216091,756839,859433,1257787,1398269,2976221,3021377,6972593,13466917,20996011。

有了梅森素数,只要求相应的2^p-1即可。素数的问题是解决了,但2^20996011是个什么概念,天文数字,再强大计算机一时半会儿也算不出来。幸好题目是拿an对1000000007取模。通过模运算可以简化问题。

模运算(2^p-1)%N=(2^p%N-1)%N,在这里等于2^p%N-1。但下面一个问题来了2^p%N怎么求?

2^p%N是一个庞大的数,传统的方法是递归,无论从空间还是时间上来说都不解决问题。幸好往日有积累,对这种变态需求,当然有特殊手段。运用蒙哥马利算法可以迅速解决,秒杀之。

最后得到an的前40个数:1,3,15,63,4095,65535,262143,73741816,536396503,140130950,487761805,319908070,106681874,373391776,317758023,191994803,416292236,110940209,599412198,383601260,910358878,532737550,348927936,923450985,470083777,642578561,428308066,485739298,419990027,287292016,202484167,389339971,848994100,273206869,853092282,411696552,876153853,90046024,828945523,697988359。

提交代码的时候,写成枚举,成功!

亿阳信通:不可表示的数相关推荐

  1. 2023年你最值得了解的信息技术-AI篇(一)

    列表 85 - 其他 辽宁省 大连优联智能 自动化生产线提供商 未融资 大连优联智能是一家自动化生产线提供商,集规划设计.制造安装.系统集成.视觉检测及AI数据智能分析于一体,可为汽车车身及发动机制造 ...

  2. 伍六七带你学算法 进阶篇-三数之和

    三数之和 难度-中等 题目:给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组. 注意 ...

  3. 使用python愉快地做高数线代题目~

    今天接触到了python,发现真是极易上手啊!对比c语言是什么鬼东西= = 诶,等下,看完教学文章发现TA在下面写了这句话 如果做了前面的内容你可能已被吸引了,觉得c语言真的是废材! 不...不是的. ...

  4. 十进制转化为二进制java代码_【模板小程序】任意长度十进制数转化为二进制(java实现)...

    妈妈再也不用担心十进制数过大了233 import com.google.common.base.Strings; import java.math.BigInteger; import java.u ...

  5. HJ86 求最大连续bit数

    描述 求一个byte数字对应的二进制数字中1的最大连续数,例如3的二进制为00000011,最大连续2个1 本题含有多组样例输入. 输入描述: 输入一个byte数字 输出描述: 输出转成二进制之后连续 ...

  6. Redis 笔记(02)— keys 键相关命令(查询数据库key数量、判断key是否存在、指定key过期时间、查看key类型、查看key剩余秒数、选择数据库、删除key、删除数据库)

    1. keys 键相关命令 命令 说明 dbsize 返回当前数据路的key数量 exists key 测试指定key是否存在 expire key seconds 为key指定过期时间 type k ...

  7. leetcode 5. Longest Palindromic Substring 字符串中的最长回文数 逐步从O(n^2)优化至线性时间

    题目 解析 思路一 暴力解法 思路二 指针+最大长度 思路3 由中间至两边找回数 思路4 Manacher's algorithm 线性时间 参考文档 题目 链接 给定一个字符串 s,找到 s 中最长 ...

  8. 数据类型对应的字节数

    20210622 https://www.icode9.com/content-4-421680.html 32位和64位常用数据结构所占字节数 20210126 1 2 4 8 1248 刚好都是2 ...

  9. LeetCode简单题之将整数转换为两个无零整数的和

    题目 「无零整数」是十进制表示中 不含任何 0 的正整数. 给你一个整数 n,请你返回一个 由两个整数组成的列表 [A, B],满足: A 和 B 都是无零整数 A + B = n 题目数据保证至少有 ...

  10. LeetCode简单题之差的绝对值为 K 的数对数目

    题目 给你一个整数数组 nums 和一个整数 k ,请你返回数对 (i, j) 的数目,满足 i < j 且 |nums[i] - nums[j]| == k . |x| 的值定义为: 如果 x ...

最新文章

  1. 妙用“IP地址冲突”揪出害群之马
  2. Android下/data/data/package_name/files读写权限
  3. cv2 python3.5 linux,ubuntu 16.04 安装 opencv3.2.0 with python 3.5
  4. python123第6周答案_Python123测验6: 组合数据类型 (第6周)
  5. wordpress胖鼠采集去限制版
  6. win10一直正在检查更新_教你解决“Win10系统更新失败后循环重启安装”的解决方法...
  7. css 怎么设置盒子水平居中,用一段css实现盒子垂直水平居中方法(8种)-案例
  8. windows 无法停止ics_x64仿真功能加入 ARM版Windows即将获得大量的应用程序
  9. 热敏电阻 温度 电阻换算
  10. python返回索引值_python取索引值
  11. Scala中的基本类型 与操作符
  12. 虚幻竞技场3中的配置文件
  13. 宠物合成养成游戏养猫养牛流量主小程序开发
  14. HTML+CSS美食静态网页设计
  15. subject 获取登录用户信息
  16. 1D mesauring
  17. C#操纵Word的坑
  18. 文字识别在高德地图数据生产中的演进
  19. 前端web:响应式Web开发优缺点总结
  20. Android实战(MediaPlayer填坑)

热门文章

  1. 以太坊分片Sharding FAQ
  2. 迁徙数据平台简单介绍
  3. Missing Parts——Alpha 第 3 季NFT作品集来啦!
  4. java写出麻将和牌的算法,麻将胡牌算法
  5. Asp.net页面跳转的方法
  6. 5个UI界面设计网站,马住了
  7. C++ 类(继承中的构造和析构)
  8. 医学生建议计算机系学生植发,00后都开始“秃”了?皮肤科专家:不想成为“地中海”,这件事情要记牢...
  9. JAVA高效批量插入数据到数据库demo
  10. springMVC文件的上传和页面静态化技术