楼主: 〇〇

Project Euler Problem 276, 268, 347

[复制链接]
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
101#
发表于 2012-2-9 01:23 | 只看该作者
我认为Problem 370应从b找起
只有b是非素数平方或立方的合数,才有可能是满足题设的b(素数平方或立方一定不满足题设,易证)

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
102#
 楼主| 发表于 2012-2-9 07:47 | 只看该作者
tree_new_bee 发表于 2012-2-8 23:53
采用上面的算法, 计算与OO相同的参数(每边不超过10000, 周长小于1e6), 时间只要2秒左右了。

with targ ...

p=q=>a=b=c恒成立,不用判断

使用道具 举报

回复
论坛徽章:
10
CTO参与奖
日期:2009-02-20 09:44:20ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30迷宫蛋
日期:2012-05-07 10:55:58茶鸡蛋
日期:2012-04-19 16:08:262012新春纪念徽章
日期:2012-01-04 11:54:462011新春纪念徽章
日期:2011-01-04 10:24:02数据库板块每日发贴之星
日期:2010-12-19 01:01:02数据库板块每日发贴之星
日期:2010-12-13 01:01:012009日食纪念
日期:2009-07-22 09:30:00优秀写手
日期:2014-02-08 06:00:12
103#
发表于 2012-2-9 08:39 | 只看该作者
〇〇 发表于 2012-2-9 07:47
p=q=>a=b=c恒成立,不用判断

恩。
我说的是你那个结果8341其实不完全。没把a=b=c的算进来。

使用道具 举报

回复
论坛徽章:
10
CTO参与奖
日期:2009-02-20 09:44:20ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30迷宫蛋
日期:2012-05-07 10:55:58茶鸡蛋
日期:2012-04-19 16:08:262012新春纪念徽章
日期:2012-01-04 11:54:462011新春纪念徽章
日期:2011-01-04 10:24:02数据库板块每日发贴之星
日期:2010-12-19 01:01:02数据库板块每日发贴之星
日期:2010-12-13 01:01:012009日食纪念
日期:2009-07-22 09:30:00优秀写手
日期:2014-02-08 06:00:12
104#
发表于 2012-2-9 08:47 | 只看该作者
本帖最后由 tree_new_bee 于 2012-2-9 08:54 编辑

改成pl/sql 后:
  1. create or replace procedure Q370(arg number default 1e6) is
  2. peri number;
  3. cnt number :=0;
  4. begin

  5.   for q in 1.. sqrt(arg) loop
  6.     for p in ceil(q/2) .. q loop
  7.       if pkg_prim2.gcd(p,q) = 1 and p+q > q*q/p then
  8.       peri := p*p + p*q + q*q;
  9.       if peri <=arg then
  10.             cnt:= cnt+ floor(arg/peri);
  11.       end if;
  12.       end if;
  13.     end loop;
  14.   end loop;
  15.   
  16.   dbms_output.put_line(cnt);      
  17. end Q370;
复制代码
SQL> exec q370(1e6)

861805

PL/SQL procedure successfully completed

Executed in 0.827 seconds

SQL> exec q370(1e7)

9712598

PL/SQL procedure successfully completed

Executed in 9.157 seconds

这样性能又提升了一个数量级, 但比起题目要求还差的远。

对上面的代码做profile, 可以看出时间消耗主要在gcd上。

其实,回头看94#列出的p/q, 就可以发现q要使用3以上的所有整数, 所以关键是要高效的找到与q互质的p,
这个问题也许要需要一些以前的关于真分数的题目的结论。


也因为这个原因, 我觉得project euler的题目,还是从前往后挨个做更可取一点。

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
105#
 楼主| 发表于 2012-2-9 09:17 | 只看该作者
tree_new_bee 发表于 2012-2-9 08:47
改成pl/sql 后:SQL> exec q370(1e6)

861805

去掉相等的,基本没有影响

create or replace procedure Q3702(arg number default 1e6) is
peri number;
cnt number :=0;
begin

  for q in 1.. sqrt(arg) loop
    for p in ceil(q/2) .. q-1 loop
      if pkg_prim2.gcd(p,q) = 1 and p+q > q*q/p then
      peri := p*p + p*q + q*q;
      if peri <=arg then
            cnt:= cnt+ floor(arg/peri);
      end if;
      end if;
    end loop;
  end loop;
  
  dbms_output.put_line(cnt+trunc(arg/3));      
end Q3702;
/
exec q3702(1E6)

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
106#
 楼主| 发表于 2012-2-9 09:58 | 只看该作者
〇〇 发表于 2012-2-9 09:17
去掉相等的,基本没有影响

create or replace procedure Q3702(arg number default 1e6) is

改变q的上界,q最大不超过1/2周长
create or replace procedure Q3702(arg number default 1e6) is
peri number;
cnt number :=0;
begin

  for q in 1.. sqrt(arg/2) loop
    for p in ceil(q/2) .. q-1 loop
      if pkg_prim2.gcd(p,q) = 1 and p+q > q*q/p then
      peri := p*p + p*q + q*q;
      if peri <=arg then
            cnt:= cnt+ floor(arg/peri);
      end if;
      end if;
    end loop;
  end loop;
  
  dbms_output.put_line(cnt+trunc(arg/3));      
end Q3702;
/

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
107#
 楼主| 发表于 2012-2-9 10:13 | 只看该作者
〇〇 发表于 2012-2-9 09:58
改变q的上界,q最大不超过1/2周长
create or replace procedure Q3702(arg number default 1e6) is
per ...

其实p也有上界,不能超过1/3周长,否则就不是最短边了,c程序验证通过
但改到pl/sql却出错了
#include <stdio.h>
#include <math.h>
#define M 10000000
int gcd(int a,int b)
{
int temp;if(a<b)/*交换两个数,使大数放在a上*/{temp=a;a=b;b=temp;}
while(b!=0)/*利用辗除法,直到b为0为止*/{temp=a%b;a=b;b=temp;}
return a;
}
int main()
{
int a;
int c;
int s=M/3;
for(int a0=2;a0<sqrt(M/3);a0++)
{a=a0*a0;
for(int c0=a0+1;c0<=sqrt(M/2);c0++)
{
if (gcd(a0,c0)==1)
{
c=c0*c0;
if( a+a0*c0>c && /*a<a0*c0 && a0*c0<c &&*/ a+a0*c0+c<=M)
s+=M/(a+a0*c0+c);
}
if(a%500000==1)
printf("%d,%d\n",a,s);
}
}
printf("%d",s);
return 1;
}

SQL> exec q3702(1E6)
853262

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
108#
 楼主| 发表于 2012-2-9 10:33 | 只看该作者
〇〇 发表于 2012-2-9 09:58
改变q的上界,q最大不超过1/2周长
create or replace procedure Q3702(arg number default 1e6) is
per ...

条件p+q > q*q/p 可以解不等式,得到p/q>(sqrt(5)-1)/2=0.618
create or replace procedure Q3702(arg number default 1e6) is
peri number;
cnt number :=0;
begin

  for q in 1.. sqrt(arg/2) loop
    for p in 0.618*q .. q-1 loop
      if pkg_prim2.gcd(p,q) = 1 and p+q > q*q/p then
      peri := p*p + p*q + q*q;
      if peri <=arg then
            cnt:= cnt+ floor(arg/peri);
      end if;
      end if;
    end loop;
  end loop;
  
  dbms_output.put_line(cnt+trunc(arg/3));      
end Q3702;
/

SQL> exec q3702(1E6)
861805

PL/SQL 过程已成功完成。

已用时间:  00: 00: 00.43
SQL> exec q3702(1E7)
9712598

PL/SQL 过程已成功完成。

已用时间:  00: 00: 04.86

使用道具 举报

回复
论坛徽章:
10
CTO参与奖
日期:2009-02-20 09:44:20ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30迷宫蛋
日期:2012-05-07 10:55:58茶鸡蛋
日期:2012-04-19 16:08:262012新春纪念徽章
日期:2012-01-04 11:54:462011新春纪念徽章
日期:2011-01-04 10:24:02数据库板块每日发贴之星
日期:2010-12-19 01:01:02数据库板块每日发贴之星
日期:2010-12-13 01:01:012009日食纪念
日期:2009-07-22 09:30:00优秀写手
日期:2014-02-08 06:00:12
109#
发表于 2012-2-9 11:22 | 只看该作者
可以细调, 但调不出数量级的变化来。 这样是不可能做出2.5e13的。

sqrt(2.5e13/2) = 3535533.9
用plsql 仅仅简单循环3535533次,也要秒级的时间。

所以要想在合理的时间内作出, 要么有什么数学方法回避循环, 要么就控制好只做一层循环, 把复杂度控制在O(n)

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
110#
 楼主| 发表于 2012-2-9 12:18 | 只看该作者
本帖最后由 〇〇 于 2012-2-9 12:19 编辑
tree_new_bee 发表于 2012-2-9 11:22
可以细调, 但调不出数量级的变化来。 这样是不可能做出2.5e13的。

sqrt(2.5e13/2) = 3535533.9


如果q为质数,那么范围内的所有p都是可以的,也可以不计算
SQL> exec q3702(1000)
4:6:9
9:12:16
16:20:25
25:30:36
25:35:49
36:42:49
25:40:64
49:56:64
49:63:81
64:72:81
49:70:100
81:90:100

49:77:121
64:88:121
81:99:121
100:110:121

121:132:144
81:117:169
100:130:169
121:143:169
144:156:169
81:126:196
121:154:196
169:182:196
121:165:225
169:195:225
196:210:225
121:176:256
169:208:256
225:240:256

121:187:289
144:204:289
169:221:289
196:238:289
225:255:289
256:272:289

169:234:324
289:306:324

144:228:361
169:247:361
196:266:361
225:285:361
256:304:361
289:323:361

169:260:400
169:273:441
532

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表