欧拉计划 发表于 2016-9-1 00:38:35

题目154:研究帕斯卡金字塔

Exploring Pascal's pyramid

A triangular pyramid is constructed using spherical balls so that each ball rests on exactly three balls of the next lower level.



Then, we calculate the number of paths leading from the apex to each position:

A path starts at the apex and progresses downwards to any of the three spheres directly below the current position.

Consequently, the number of paths to reach a certain position is the sum of the numbers immediately above it (depending on the position, there are up to three numbers above it).

The result is Pascal's pyramid and the numbers at each level n are the coefficients of the trinomial expansion (x + y + z)n.

How many coefficients in the expansion of (x + y + z)200000 are multiples of 1012?

题目:

三角状的金字塔是用圆球建造的:每个球都与下一层的三个球相接触。



于是,我们计算从顶点到任一点的路径数:

路径是从顶点开始,从下一层相接触的三个球中任选一个一直往下走。

那么,到达某一位置的路径的条数就是到达它上一层的路径数之和(取决于具体位置,一个球,最多可能有三条路径可以从上层到该位置,所以,最多只有三个路径数)。

这个结果就是帕斯卡金字塔,第n层的路径数是三项式乘方 (x + y + z)n的系数.

请问,(x + y + z)200000 的系数中,有多少个是 1012倍数?

gunjang 发表于 2017-9-4 14:33:03

#(x + y + z)^n = ∑(n!/(r!* s!* t!) * x^r * y^s * z^t) ,r+s+t=n
所以问题变成 n!/(r!* s!* t!) 里有多少10^12的倍数,r+s+t=n
10^12分解成因子就是12个2和12个5
问题变成n!/r!s!t!有几个的2和5的因子数都大于等于12
算法很简单
只所以采用pascal实在是因为python计算太慢了(也可能我的算法不够优化)
delphi7运行的话大概1分半,python目测起码10个小时。。。
program p154;

{$APPTYPE CONSOLE}

uses
SysUtils, Types, Windows,Math;
const
maxn = 200000;
type
nlist = array of integer;
var
st: DWord;
twolist, fivelist: nlist;
cnt: integer;
r,s,t: integer;

function getXcountin1n(const x: word): nlist;
var
    cnt: integer;
    i,i1: integer;
begin
    cnt := 0;
    for i:=0 to x-1 do
      result := 0;
    i := x;
    while i <= maxn do
    begin
      i1 := i;
      while (i1 > 0) and (i1 mod x = 0) do
      begin
      inc(cnt);
      i1 := i1 div x
      end;
      for i1:= i to i+x-1 do
      result := cnt;
      inc(i, x);
    end;
end;

begin
st := gettickcount();
twolist := getXcountin1n(2);
fivelist := getXcountin1n(5);
cnt := 0;
for r:= 0 to maxn do
begin
for s:= 0 to (maxn-r) do
begin
    t := maxn-r-s;
    if (twolist-twolist-twolist-twolist >= 12) and (fivelist-fivelist-fivelist-fivelist >= 12) then
       inc(cnt);
end;
end;

writeln(cnt);//479742450 87.4s
writeln(format('cost %n s', [(gettickcount-st)/1000]));
readln; //wait Enter
end.

guosl 发表于 2022-9-21 20:08:44

本帖最后由 guosl 于 2022-9-21 20:19 编辑

思路参考上面的帖子
/*
答案:479742450
耗时:1.24439秒(R5 5600G)
*/
#include <iostream>
#include <omp.h>
using namespace std;

const int N = 200000;
int p2, p5;

int main(void)
{
long long nCount = 0;
#pragma omp parallel shared (p2,p5) reduction(+:nCount)
{
#pragma omp for
    for (int i = 2; i <= N; ++i)
    {
      int k = 2;
      while (k <= i)
      {
      p2 += i / k;
      k *= 2;
      }
      k = 5;
      while (k <= i)
      {
      p5 += i / k;
      k *= 5;
      }
    }
    for (int i = 0; i <= N; ++i)
    {
#pragma omp for
      for (int j = 0; j <= N - i; ++j)
      {
      int k = N - i - j;
      int c2 = p2 - p2 - p2 - p2;
      int c5 = p5 - p5 - p5 - p5;
      if (c2 >= 12 && c5 >= 12)
          ++nCount;
      }
    }
}
cout << nCount << endl;
return 0;
}
页: [1]
查看完整版本: 题目154:研究帕斯卡金字塔