方格取数 (Standard IO)
题意/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。包含一个整数表示所求最小值。
题解/solution:
将矩阵的各个格子分解为,用矩阵A表示各个格子有多少个因数2,用矩阵B表示各个格子有多少个因数5。最后枚举一遍两个矩阵,得出从左上角到右下角经过最少的2和5。最后判断哪个小即可。
代码/Code:
var
n,m,numa,numb:longint;
a,b,ab:array [0..1001,0..1001] of longint;
procedure init;
var
i,j,t,k:longint;
begin
readln(n,m);
for i:=1 to n do
for j:=1 to m do
begin
read(t);
k:=t;
while t mod 2=0 do
begin
t:=t div 2;
inc(a[i,j]);
end;
while k mod 5=0 do
begin
k:=k div 5;
inc(b[i,j]);
end;
end;
numa:=maxlongint;
numb:=maxlongint;
end;
function min(o,p:longint):longint;
begin
if o<p then exit(o);
exit(p);
end;
procedure main;
var
i,j:longint;
begin
for i:=1 to n do
for j:=1 to m do
if i=1 then ab[i,j]:=ab[i,j-1]+a[i,j] else
if j=1 then ab[i,j]:=ab[i-1,j]+a[i,j] else
ab[i,j]:=min(ab[i-1,j],ab[i,j-1])+a[i,j];
numa:=ab[n,m];
fillchar(ab,sizeof(ab),0);
for i:=1 to n do
for j:=1 to m do
if i=1 then ab[i,j]:=ab[i,j-1]+b[i,j] else
if j=1 then ab[i,j]:=ab[i-1,j]+b[i,j] else
ab[i,j]:=min(ab[i-1,j],ab[i,j-1])+b[i,j];
numb:=ab[n,m];
write(min(numa,numb));
end;
begin
init;
main;
end.