Julia : The Power Sum的算法

HackerRank中有一道算法题,
这里写图片描述

即有一个数(input),可以由一个序列[1 2 3 4 …..]的power(幂)的级别(power的值为2时,即平方,为3即立方,…..)相加得到。请问有多少种可能?

具体地说:

当:input =10 ;power =2;
有 10 =1^2 +3^2; 有一种构建方式。
当:input =100;power =2;
有100=10^2
= 6^2+8^2
=1^2+3^2+5^2+7^2 ;共三种构建方式。

也就是当input(<=1000)、power(>=2)确定时,有多少种组合?

一、构建一个系数矩阵(0,1)
在选的序列中,比如当power=2,序列[1,4,9,16,25,36,49,64,81,100]的序数是关键,本来是可以一个个试算的,但是放在一个矩阵中,会更方便。

下面的任务是构建一个穷尽的(0,1)矩阵,列有max_power_n项,即input开power根得到的值(input=100, power=2,max_power_n =sqrt(100)=10)。

思路是从mat =[1 0;1 1; 0 1; 0 0 ]来不断构建一个能包括各种情况的(0,1)矩阵,

其中:列数是:max_power_n。行数呢?
行数:是 2^(max_power_n) 。因为,每一列相当于一个变量,其值只有2种可能,0或1,也就会,所有的可能就是这个了。

function get_matrix(n::Int64)
   data =[];
   if n<2
      error("n<1!");
   else
      mat =[1 0;1 1; 0 1; 0 0 ];
      for i=2:n-1
          temp1 =hcat(mat,zeros(mat)[:,1]);
          temp2= hcat(mat,ones(mat)[:,1]);
          data =[temp1;temp2];
          mat =copy(data);
       end
          return data
    end
 end

二、输出函数

以下的函数可以得到总体的结果:

function get_result(input,power)
   max_power_n =Int64(ceil(input^(1/power)));
   out_matrix =get_matrix(max_power_n);
   sum_matrix =out_matrix*(collect(1:max_power_n).^power);
   output =sum(sum_matrix.==input);
   println("input:$input power:$power =>result :$output");
   return output;
end

output:

julia> get_result(100,2)
input:100 power:2 =>result :3
3

julia> get_result(10,2)
input:10 power:2 =>result :1
1

julia> get_result(10,3)
input:10 power:3 =>result :0
0

julia> get_result(100,4)
input:100 power:4 =>result :0
0

julia> get_result(120,2)
input:120 power:2 =>result :4

但是,如何看到明细的构成组合呢?

三、如何输出明细的结果?

既然要输出明细,那就让我们做一些优化:

function get_result_detail(input,power)
   max_power_n =Int64(ceil(input^(1/power)));
   out_matrix =get_matrix(max_power_n);
   series =collect(1:max_power_n).^power;
   sum_matrix =out_matrix*series;
   vec =sum_matrix.==input;
   println_detail(out_matrix,series,vec,input,power);
end

让我们写一个输出明细结果的函数:

function println_detail(out_matrix,series,vec,input,power)
    row,col=size(out_matrix)
    n =0;
    for i =1:row
       if vec[i]==true
          is_print_row =false;
          n =n+1;
          for j=1:col
             mat = out_matrix[i,j];
             ser = series[j];
             is_print_row ==false && print("$n th: =>");
             is_print_row =true;
             if mat==1 
                 print(" $ser ");
             end
          end
          print("\n");
       end
    end
    println("input:$input power:$power => total result :$n");
end

四、优化的结果输出

output_detail =>

julia> get_result_detail(100,2)
1 th: => 1  9  16  25  49
2 th: => 36  64
3 th: => 100
input:100 power:2 => total result :3

julia> get_result_detail(102,2)
1 th: => 1  16  36  49
2 th: => 4  9  25  64
3 th: => 1  4  16  81
input:102 power:2 => total result :3

julia> get_result_detail(225,2)
1 th: => 9  16  36  64  100
2 th: => 25  36  64  100
3 th: => 1  4  9  16  25  49  121
4 th: => 4  36  64  121
5 th: => 4  100  121
6 th: => 4  16  25  36  144
7 th: => 1  16  64  144
8 th: => 81  144
9 th: => 4  16  36  169
10 th: => 4  9  16  196
11 th: => 4  25  196
12 th: => 225
input:225 power:2 => total result :12

这下明细也可以看清楚了。

有一个问题,为什么power不能为1?我认为如果power为1,若input较大,你想象一下,这个矩阵得多大,会导致直接内存溢出。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值