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较大,你想象一下,这个矩阵得多大,会导致直接内存溢出。