projecteuler No.104 Pandigital Fibonacci ends
来源:互联网 发布:网络侠义游戏辅助论坛 编辑:程序博客网 时间:2024/05/21 17:02
题目链接:
Problem 104 Pandigital Fibonacci ends
题目104:找出前九位和后九位数字为pandigital的斐波那契数。
通过人数:8537
题目分析:
这道题就是从斐波那契数列中选择最小的符合条件的项。由于涉及的数比较大,考虑利用java的高精度类。
我最初的代码是这样的:
BigInteger F[] = new BigInteger[100000];F[1] = new BigInteger("1");F[2] = new BigInteger("1");outer:for (int i = 3; i < 100000; i++){F[i] = F[i-1].add(F[i-2]);if (i%100 == 0)System.out.print(i+"\n");if (i > 57000){int mark[] = new int[10];String temp = F[i].toString();for (int j = 0; j < 9; j++)mark[temp.charAt(j) - '0']++;for (int j = 1; j <= 9; j++)if (mark[j] != 1)continue outer;for (int j = 1; j <= 9; j++)mark[temp.charAt(temp.length() - j) - '0']--;for (int j = 1; j <= 9; j++)if (mark[j] != 0)continue outer;System.out.print(F[i]);break;}}
单纯地计算斐波那契数列F[]并将其转化为字符串再检查题目所需的要求。
但是发现在10000以内没有满足题目要求的,在10000以上就算得非常慢...算100000要几十分钟的时间。
再检查代码,发现是BigInteger.toString算得太慢了。看来BigInteger使用的是2进制进行内部存储,而高精度的进制转换差不多O(n^2)的时间复杂度(n为有效位数),实在是占用了太多的时间。
然后考虑到,如果只需要检测后9位,就只需要在运算时保留后9位就好了。而检测前9位的时候,考虑到a+b=c中,a,b有一定百分率的误差后,c的误差百分率不超过a,b的最大值。而这要是想要影响到结果的前几位,只有误差产生进位和退位并影响到前面很多位时才会发生。而这种事件的发生概率,随着精度每增加一位(即误差减少十倍),就会减少10倍。只要多保留10位的精度,在若干万的测试数据中就很难会遇到了。(尤其是斐波那契数列的数位排列还几乎是随机的...)于是我就用另一个数组保留斐波那契数列的前十几位。这样前9位就有极大的概率是准确的了。
解题过程:
一、常量及初始化:
BigInteger N = new BigInteger("1000000000");BigInteger NN = new BigInteger("1000000000000000");BigInteger F[] = new BigInteger[1000000];F[1] = new BigInteger("1");F[2] = new BigInteger("1");BigInteger G[] = new BigInteger[1000000];G[1] = new BigInteger("1");G[2] = new BigInteger("1");数列F计算尾数,G计算首数。N用来让F去模,NN用来控制G的精度。
二、数列求值:
outer:for (int i = 3; i < 1000000; i++){F[i] = F[i-1].add(F[i-2]);G[i] = G[i-1].add(G[i-2]);if (F[i].compareTo(N) > 0)F[i]=F[i].remainder(N);if (G[i].compareTo(NN) > 0){G[i] = G[i].divide(BigInteger.TEN);G[i - 1] = G[i - 1].divide(BigInteger.TEN);}即使如上所述地对F和G均保留斐波那契数列的部分位。
三、筛选:
int m[] = new int[10];String s1 = F[i].toString();if (s1.length() < 9)continue;for (int j = 0; j < 9; j++)m[s1.charAt(j) - '0']++;for (int j = 1; j <= 9; j++)if (m[j] != 1)continue outer;String s2 = G[i].toString();if (s2.length() < 9)continue;for (int j = 0; j < 9; j++)m[s2.charAt(j) - '0']--;for (int j = 1; j <= 9; j++)if (m[j] != 0)continue outer;System.out.print(i+"\n");这段也没什么可说的了,考察F[i]和G[i]的后9位和前9位。排除掉不满足条件的,剩下的就是满足条件的了。最后输出329468。
分析:其实也可以直接写一个基于10进制的高精度整数类。这样转string就会快很多...不过用BigInteger不就是因为偷懒么~O(∩_∩)O~
以上只是我做题时的解法。
如果有更好的解法、更好的思路,欢迎评论讨论~O(∩_∩)O~
- projecteuler No.104 Pandigital Fibonacci ends
- PE 104 Pandigital Fibonacci ends (数学fibonacci)
- projecteuler---->problem=32----Pandigital products
- [projecteuler]Even Fibonacci numbers
- projecteuler No.205 Dice Game
- projecteuler No.96 Su Doku
- projecteuler No.77 Prime summations
- projecteuler No.120 Square remainders
- projecteuler No.124 Ordered radicals
- projecteuler No.78 Coin partitions
- projecteuler No.83 four ways
- projecteuler No.66 Diophantine equation
- projecteuler No.100 Arranged probability
- projecteuler.net 2--Even Fibonacci numbers
- projecteuler No.68 Magic 5-gon ring
- projecteuler No.64 Odd period square roots
- projecteuler No.80 Square root digital expansion
- projecteuler No.90 Cube digit pairs
- 装机折腾之U310装Win7SP1_X64
- HADOOP 2.0 YARN应用程序的执行流程和开发
- 微信5.0公众号运营有6大误区
- 那些年·我们读过的专业书籍
- 那些年·我们读过的专业书籍
- projecteuler No.104 Pandigital Fibonacci ends
- 为什么rand()每次产生的随机数都一样
- 几个比较好的countdown js
- 机房收费系统 实现图
- SQL Server 2008 with(nolock)的使用原因及数据库锁,隔离级别简介
- 当当网与1号店相互入驻
- 寒假获得的小知识
- 2014年2月7日星期五(7-3,消除了背面的3D线框立方体)
- 【D3DX日记】D3D与D3DX的区别