题目

Square digit chains

A number chain is created by continuously adding the square of the digits in a number to form a new number until it has been seen before.

For example,

44 → 32 → 13 → 10 → 1 → 1
85 → 89 → 145 → 42 → 20 → 4 → 16 → 37 → 58 → 89

Therefore any chain that arrives at 1 or 89 will become stuck in an endless loop. What is most amazing is that EVERY starting number will eventually arrive at 1 or 89.

How many starting numbers below ten million will arrive at 89?


平方数字链

将一个数的所有数字的平方相加得到一个新的数,不断重复直到新的数已经出现过为止,这构成了一条数字链。

例如,

44 → 32 → 13 → 10 → 1 → 1
85 → 89 → 145 → 42 → 20 → 4 → 16 → 37 → 58 → 89

可见,任何一个到达1或89的数字链都会陷入无尽的循环。更令人惊奇的是,从任意数开始,最终都会到达1或89。

有多少个小于一千万的数最终会到达89?

解题

这个链式的之前好有有个题目和这个差不多的,直接暴力很简单。

JAVA

package Level3;

public class PE092{
static void run(){
int MAX = 10000000;
int count = 0;
for(int num=1;num<=MAX;num++){
int numx = num;
if(is89(numx))
count +=1;
}
System.out.println(count);
}
// 8581146
// running time=1s973ms
static boolean is89(int num){
int next_num = num;
while(true){
if(next_num == 89) break;
if(next_num == 1) break;
next_num = nextNum(next_num);
}
if(next_num ==89)
return true;
return false;
}
static int nextNum(int num){
int next_num = 0;
while(num!=0){
int tmp = num%10;
next_num += tmp*tmp;
num/=10;
}
return next_num;
} public static void main(String[] args) {
long t0 = System.currentTimeMillis();
run();
long t1 = System.currentTimeMillis();
long t = t1 - t0;
System.out.println("running time="+t/1000+"s"+t%1000+"ms"); }
}

Python运行时间比较长

# coding=gbk

import time as time
from itertools import combinations
def run():
MAX = 10000000
count = 0
for num in range(1,MAX):
if is89(num):
count+=1
print count # 8581146
# running time= 305.638000011 s
def next_num(num):
return sum([a*a for a in map(int ,str(num))]) def is89(num):
while True:
if num == 89 or num == 1:
break
num = next_num(num)
if num == 89:
return True
return False t0 = time.time()
run()
t1 = time.time()
print "running time=",(t1-t0),"s"

85 → 89 → 145 → 42 → 20 → 4 → 16 → 37 → 58 → 89

题目给了一个这样的提示,只有我们知道中间的数,就一定能到89

最大值是9999999 ,nextnum = 9*9*7 = 567 ,可以定义一个568的数组来保存中间的计算结果能到达89的。

这里我只定义一个boolean数组Judge。先保存前一步的值numx, 若nextnum[numx] == 89 则,则Judge[numx] ==True

在以后我们可以先判断nextnum在Judge中是否是true,true就不用计算了。

当然如果定义一个矩阵,保存所有的计算中间值,这个比较复杂啊,对了,可以定义一个set,也很好判断是否存在。下面尝试一下。

下面run2() 是定义boolean数组的,run3()是定义两个set的。

定义boolean数组的  对所有的值是否都能判断? 这里就不知道了。所以才想起了定义set的

package Level3;

import java.util.TreeSet;

public class PE092{
static void run3(){
int MAX = 10000000;
int count =0;
TreeSet<Integer> path = new TreeSet<Integer>();
TreeSet<Integer> judge = new TreeSet<Integer>();
for(int num =2;num<MAX;num++){
int numx = nextNum(num);
if(path.contains(numx)){
count +=1;
}else{
while(true){
judge.add(numx);
numx = nextNum(numx);
if(path.contains(numx) || numx==89){
path.addAll(judge);
judge.clear();
count +=1;
break;
}
if(numx == 1){
judge.clear();
break;
}
}
}
}
System.out.println(count);
}
// 8581146
// running time=0s953ms // 9*9*7 = 567 定义一个长度是567的数组保存之前计算过程中的值
// 若以89结束定义为true 以后认为是true就可以直接认为是89结束了
static void run2(){
int MAX = 10000000;
int count = 0;
boolean Judge[] = new boolean[568];
for(int num =1;num<MAX;num++){
// 求下一个数
int numx = nextNum(num);
// 下一个数是否计算过
if(Judge[numx]){
count+=1;
}else{
while(true){
// 继续求下一个数
int tmp = nextNum(numx);
// 计算过或者 遇到89的时候把之前的数更行Judge[numx]
if(Judge[tmp] || tmp==89){
count+=1;
Judge[numx] = true;
break;
}
if(tmp ==1) break;
numx = tmp; }
}
}
System.out.println(count);
}
// 8581146
// running time=0s944ms
static void run(){
int MAX = 10000000;
int count = 0;
for(int num=1;num<=MAX;num++){
int numx = num;
if(is89(numx))
count +=1;
}
System.out.println(count);
}
// 8581146
// running time=1s973ms
static boolean is89(int num){
int next_num = num;
while(true){
if(next_num == 89) break;
if(next_num == 1) break;
next_num = nextNum(next_num);
}
if(next_num ==89)
return true;
return false;
}
static int nextNum(int num){
int next_num = 0;
while(num!=0){
int tmp = num%10;
next_num += tmp*tmp;
num/=10;
}
return next_num;
} public static void main(String[] args) {
long t0 = System.currentTimeMillis();
run2();
long t1 = System.currentTimeMillis();
long t = t1 - t0;
System.out.println("running time="+t/1000+"s"+t%1000+"ms"); }
}

Python

# coding=gbk

import time as time
def run2():
MAX = 10000000
count = 0
path=[]
judge=[]
for num in range(1,MAX):
numx = next_num(num)
if numx in path:
count +=1
else:
while True:
judge.append(numx)
numx = next_num(numx)
if numx in path or numx == 89:
count+=1
path +=judge
judge=[]
break
if numx ==1:
judge = []
break
print count
#
# running time= 165.453000069 s

Project Euler 92:Square digit chains 平方数字链的更多相关文章

  1. Project Euler 92:Square digit chains C++

    A number chain is created by continuously adding the square of the digits in a number to form a new ...

  2. (Problem 92)Square digit chains

    A number chain is created by continuously adding the square of the digits in a number to form a new ...

  3. Project Euler 51: Prime digit replacements

    通过替换*3这样一个两位数的第一位,我们可以发现形成的九个数字有六个是质数,即13, 23,43,53,73,83.类似的,如果我们用同样的数字替换56**3这样一个五位数的第三位和第四位,会生成56 ...

  4. Project Euler 56: Powerful digit sum

    一个古戈尔也就是\(10^{100}\)是一个天文数字,一后面跟着一百个零.\(100^{100}\)更是难以想像的大,一后面跟着两百个零.但是尽管这个数字很大,它们各位数字的和却只等于一.考虑两个自 ...

  5. Project Euler 57: Square root convergents

    五十七.平方根收敛(Square root convergents) 二的平方根可以表示为以下这个无穷连分数: \[ \sqrt 2 =1+ \frac 1 {2+ \frac 1 {2 +\frac ...

  6. Project Euler #80: Square root digital expansion

    from decimal import getcontext, Decimal def main(): n = int(raw_input()) p = int(raw_input()) getcon ...

  7. 【easy】367. Valid Perfect Square 判断是不是平方数

    class Solution { public: bool isPerfectSquare(int num) { /* //方法一:蜜汁超时…… if (num < 0) return fals ...

  8. Project Euler 20 Factorial digit sum( 大数乘法 )

    题意:求出100!的各位数字和. /************************************************************************* > Fil ...

  9. Project Euler 16 Power digit sum( 大数乘法 )

    题意: 215 = 32768,而32768的各位数字之和是 3 + 2 + 7 + 6 + 8 = 26. 21000的各位数字之和是多少? 思路:大数乘法,计算 210 × 100 可加速计算,每 ...

随机推荐

  1. LiteHttp:一款‘智能’的HTTP框架类库

    LiteHttp:一款‘智能’的HTTP框架类库(转自github) 简介 LiteHttp是一款简单.智能.灵活的HTTP框架库,它在请求和响应层面做到了全自动构建和解析,主要用于Android快速 ...

  2. PHP环境搭建(Windows8.1+IIS8.5+PHP5.6+PHPStorm)

    第一次接触php是在2014-5月份左右,当时是自己的主攻方向是C#,对php比较排斥, 其中很多一部分原因,就是PHP的断点调试一直无法配置成功,用echo打印日志的方式排错,使得自己对php心生怨 ...

  3. GridView中的荧光棒效果

    使用 ASP.NET中的GridView控件的时候会遇到这个效果,当时觉得很神奇,其实就是两句代码的事儿,可是时间长了,有点儿忘了,今天练习一下, 顺便把删除的时候弹出js中的confirm对话框也写 ...

  4. Python脚本控制的WebDriver 常用操作 <十九> 获取测试对象的状态

    下面将使用webdriver来模拟测试中观察测试对象的状态的操作 测试用例场景 在web自动化测试中,我们需要获取测试对象的四种状态 是否显示.使用element.is_displayed()方法: ...

  5. Python中的除法

    在C/C++语言对于整形数执行除法会进行地板除(舍去小数部分).例如 int a=15/10; a的结果为1. 同样的在Java中也是如此,所以两个int型的数据相除需要返回一个浮点型数据的时候就需要 ...

  6. 幻灯片slider

    <script src="{$GetInstallDir}web/scripts/jquery-1.3.1.js"></script> <style& ...

  7. 2016 医疗项目 Bootstrap 自适应页面布局(1)

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  8. android之TextView

    TextView 常用属性说明: lines:设置可以显示的文本行数,且不管文本是否足够占用这些行的空间,该组件都会占用这些行的空间高度. maxLines:设置最大显示的行数,随文本改变,占用的行数 ...

  9. SQL_SERVER_2008升级SQL_SERVER_2008_R2办法 (一、升级;二、重新xie载安装)

    SQL_SERVER_2008升级SQL_SERVER_2008_R2两种办法   今天将由于需要就将我的SQL 2008升级到SQL 2008 R2. 说到为什么要升级是因为,因附加数据库时发现报错 ...

  10. 巨大bug

    //数据结构关于课程设计--------图书馆管理系统的设计 #include <stdio.h> #include <stdlib.h> #include <strin ...