Project Euler 92: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 平方数字链的更多相关文章
- 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 ...
- (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 ...
- Project Euler 51: Prime digit replacements
通过替换*3这样一个两位数的第一位,我们可以发现形成的九个数字有六个是质数,即13, 23,43,53,73,83.类似的,如果我们用同样的数字替换56**3这样一个五位数的第三位和第四位,会生成56 ...
- Project Euler 56: Powerful digit sum
一个古戈尔也就是\(10^{100}\)是一个天文数字,一后面跟着一百个零.\(100^{100}\)更是难以想像的大,一后面跟着两百个零.但是尽管这个数字很大,它们各位数字的和却只等于一.考虑两个自 ...
- Project Euler 57: Square root convergents
五十七.平方根收敛(Square root convergents) 二的平方根可以表示为以下这个无穷连分数: \[ \sqrt 2 =1+ \frac 1 {2+ \frac 1 {2 +\frac ...
- Project Euler #80: Square root digital expansion
from decimal import getcontext, Decimal def main(): n = int(raw_input()) p = int(raw_input()) getcon ...
- 【easy】367. Valid Perfect Square 判断是不是平方数
class Solution { public: bool isPerfectSquare(int num) { /* //方法一:蜜汁超时…… if (num < 0) return fals ...
- Project Euler 20 Factorial digit sum( 大数乘法 )
题意:求出100!的各位数字和. /************************************************************************* > Fil ...
- Project Euler 16 Power digit sum( 大数乘法 )
题意: 215 = 32768,而32768的各位数字之和是 3 + 2 + 7 + 6 + 8 = 26. 21000的各位数字之和是多少? 思路:大数乘法,计算 210 × 100 可加速计算,每 ...
随机推荐
- Linux mkisofs 创建光盘镜像文件(Linux指令学习笔记)
mkisofs命令 创建光盘文件的系统的命令是mkisofs.光盘系统有多种格式,利用Linux系统提供的光盘文件系统创建 命令mkisofs,可以创建多种iso9660文件系统. 我们一般不用mki ...
- nss_12 上传文件后返回jsonresult结果,IE中出现文件下载框
因为控制器返回的是JsonResult, 但是在IE8中一直返回文件下载的对话框. 转到谷歌浏览器倒没有问题. 网上找的方法, 要么是跟到一个新的成功页面, 要么是直接返回html, 觉得应该有更好的 ...
- 什么是AJAX技术及其常识
1.什么是Ajax? Ajax的全称是:AsynchronousJavaScript+XML 2.Ajax的定义: Ajax不是一个技术,它实际上是几种技术,每种技术都有其独特这处,合在一起就成了一个 ...
- laravel--has方法--查看关联关系
has()方法可以用来查询是否有关联关系的一个东西,一般其他的has方法 就是判断这个里面有没有值 $packageOrders = Company::has('packages')->get( ...
- 纯js分页代码(简洁实用)
纯js写的分页代码. 复制代码代码如下: //每页显示字数 PageSize=5000; //分页模式 flag=2;//1:根据字数自动分页 2:根据[NextPage]分页 //默认页 start ...
- centos问题集锦
一. 为什么新装的centos系统无法使用xshell,putty等工具连接? 原因:sshd服务没有启动. 解决: 1)使用命令rpm -qa | grep ssh查看是否已经安装了ssh 2)使用 ...
- require.js入门指南(一)
*:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...
- npm,grunt,less,sass,typescript
typescript http://www.typescriptlang.org sass http://sass-lang.com/ less http://lesscss.org/ bow ...
- MVC 删除文件
protected void DeleteTempFiles(string iFileName) { FileInfo f = new FileInfo(iFileName); DirectoryIn ...
- linux 命令小结
chkconfig --list 查询所有服务运行情况 修改文件夹权限: 在Linux中,权限的所有者分为用户权限,组权限和其他权限,分别是用字母u, g, o 代表权限分为:读 r , 写 w , ...