方格取数 (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.



原文地址:https://www.cnblogs.com/zyx-crying/p/9319620.html