Description
给定一个N*M的矩阵,记录左上角为(1,1),右下角为(N,M),现在从(1,1)开始取数,每次只能向下或向右移动一个单位,最终到达(N,M),我们把路径上所有的数相乘,记为C。使C的结果最大已经不能满足我们了,现在我们想让C末尾的零最少。
Ps.11000末尾有3个零,100000100末尾有2个零。
Input
输入文件matrix.in的第一行包含两个正整数N,M表示矩阵大小。
接下来N行每行M个正整数给出整个矩阵。
Output
输出文件名为matrix.out。包含一个整数表示所求最小值。
Sample Input
3 3
1 2 3
10 5 100
10 8 9
Sample Output
1
Data Constraint
Hint
【数据规模和约定】
30%的数据满足 N , M ≤ 5;
100%的数据满足 1 < N , M ≤ 1000,所有输入数据不超过32位整范围。
分析:一看到末尾0,就能想起质因数2*5=10。也就是说有一个矩阵,对答案有贡献的只有这个数2的因数个数和5的因数个数。首先预处理出每个数的2,5因数个数。
对于样例,可得
0 1 0 0 0 0
A=1 0 2 B=1 1 2
1 3 0 1 0 0
我们知道,对于任何一条路径,a为2因数的总数,b为5因数的总数,他的答案就是路径上min(a,b)。我们只需求出两个图中(1,1)à(n,m)的2,5因数最小值,再在这两个最小值中取最小值。证明:我们求出的第一条路径为2因数最小的,如果答案想更小,那么一定要5的因数比他小,而第二条路径是5最小的。如果第二条没有第一条大,那第一条就是最优的,否则第二条为最优的。
程序:
var
a,b:array[0..1000,0..1000] of longint;
n,m:longint;
procedure init;
vari,j,s,t:longint;
begin
readln(n,m);
fori:=1 to n do
forj:=1 to m do
begin
t:=0;
read(s);
whiles mod 2=0 do
begin
inc(t);
s:=s div 2;
end;
a[i,j]:=t;
t:=0;
whiles mod 5=0 do
begin
inc(t);
s:=s div 5;
end;
b[i,j]:=t;
end;
end;
function min(x,y:longint):longint;
begin
ifx<y then exit(x)
else exit(y);
end;
procedure dp;
vari,j,ansa,ansb:longint;
f:array [0..1000,0..1000] of longint;
begin
fori:=1 to n do
forj:=1 to m do
ifi=1 then f[i,j]:=f[i,j-1]+a[i,j]
else
begin
ifj=1 then f[i,j]:=f[i-1,j]+a[i,j]
else f[i,j]:=min(f[i-1,j],f[i,j-1])+a[i,j];
end;
ansa:=f[n,m];
fillchar(f,sizeof(f),0);
fori:=1 to n do
forj:=1 to m do
ifi=1 then f[i,j]:=f[i,j-1]+b[i,j]
else
begin
ifj=1 then f[i,j]:=f[i-1,j]+b[i,j]
else f[i,j]:=min(f[i-1,j],f[i,j-1])+b[i,j];
end;
ansb:=f[n,m];
writeln(min(ansa,ansb));
end;
begin
init;
dp;
end.