欧拉计划:第28题,29题,第30题

101 篇文章 7 订阅
52 篇文章 0 订阅


28题

从数字1开始向右顺时针方向移动,可以得到如下的5×5的螺旋:

21 22 23 24 25
20  7 8  9 10
19  6  1 2 11
18  5 4  3 12
17 16 15 14 13

可以算出对角线上数字之和是101.

1001×1001的螺旋中对角线上数字之和是多少?



程序如下:

use strict;
use warnings;

my $i;
my $i_sum;
my $all_sum=1;

for($i=3;$i<1002;$i+=2)
{
	$i_sum=4*$i**2-6*$i+6;
	$all_sum=$all_sum+$i_sum;
}
print "$all_sum\n";

结果如下:

C:\WINDOWS\system32\cmd.exe /c perl "C:\Documents and Settings\Administrator\桌
面\a.pl"
669171001
Hit any key to close this window...





29题

考虑 ab 在 2 ≤ a ≤ 5,2 ≤ b ≤ 5下的所有整数组合:

2 2=4, 2 3=8, 2 4=16, 2 5=32
3 2=9, 3 3=27, 3 4=81, 3 5=243
4 2=16, 4 3=64, 4 4=256, 4 5=1024
5 2=25, 5 3=125, 5 4=625, 5 5=3125

如果将这些数字排序,并去除重复的,我们得到如下15个数字的序列:

4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125

ab 在 2 ≤ a ≤ 100,2 ≤ b ≤ 100 下生成的序列中有多少个不同的项?

C:\WINDOWS\system32\cmd.exe /c perl "C:\Documents and Settings\Administrator\桌
面\a.pl"
9183
Hit any key to close this window...



30题

这个题目的难点就是判断范围了,也就是从什么时候开始就肯定不会成立了,因为不可能这是一个无限的循环。

我们取极限值,假设每一位都是数字9.每一位数的5次方也就是9^5=59049.

只有一位的时候没有问题,因为有1的存在。我们要找的就是最大的值

两位的时候最大是99肯定也没有问题

三位的时候也没有问题

四位的时候也没有问题。

5位的时候也可以。因为9的5次方就是一个5位数。

6位数也是可以的,我们来看一下,假如说6位都是9.最后的结果就是6*9^5=354294是一个六位数。

7位的时候,结果最大是7*9^5=413343也是一个6位数,肯定小于七位数。

所以我们通过分析,最大不会超过354294.

那么我们进行循环判断就Ok了。相比于其他的编程,perl的一个很大的优点就是能够用split把一个数字分成各个部分,而不用进行除法求余这么麻烦!


程序如下:

use strict;
use warnings;
use bignum;

my $start_time=time;
my $sum=0;
my @num;
my $num;
my $i;
my $result=0;


for($i=2;$i<6*9**5;$i++)
{
	$sum=0;
	@num=split//,$i;
	foreach $num(@num)
	{
		$sum=$sum+$num**5;
	}
	if($sum==$i)
	{
		$result=$result+$sum;
	}
}

print "$result\n";
my $long=time-$start_time;
print "$long\n";

结果如下:

C:\WINDOWS\system32\cmd.exe /c perl "C:\Documents and Settings\Administrator\桌
面\a.pl"
443839
190
Hit any key to close this window...

用了190秒,还是很有待优化的。

然后我看了答案以后

看到意大利一个高人的程序及其简单。

3秒搞定问题。

程序如下:

#!/usr/bin/perl -l

my $start_time=time;
use strict;
use warnings;
use List::Util qw/sum/;

print sum grep { $_ == sum map $_**5, /./g } 2..6*9**5;
my $long=time-$start_time;
print "$long\n";
__END__
这确实是一种境界了。

我也不是很明白。

大家有兴趣可以自己分析一下。


结果如下:


C:\WINDOWS\system32\cmd.exe /c perl "C:\Documents and Settings\Administrator\桌
面\b.pl"
443839
3

Hit any key to close this window...


后来我发现我的程序只要两秒钟;只要把use bignum去掉,原来这也是很占用资源的。什么东西都是适可而止,大的东西没有必要一定用,东西够用就好!

程序如下:

use strict;
use warnings;

my $start_time=time;
my $sum=0;
my @num;
my $num;
my $i;
my $result=0;


for($i=2;$i<6*9**5;$i++)
{
	$sum=0;
	@num=split//,$i;
	foreach $num(@num)
	{
		$sum=$sum+$num**5;
	}
	if($sum==$i)
	{
		$result=$result+$sum;
	}
}

print "$result\n";
my $long=time-$start_time;
print "$long\n";
结果如下:

C:\WINDOWS\system32\cmd.exe /c perl "C:\Documents and Settings\Administrator\桌
面\a.pl"
443839
2
Hit any key to close this window...






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值