jzoj 2541. 【NOIP2011模拟9.1】方格取数

发布于 2019-03-25  935 次阅读


题目描述

给定一个N*M的矩阵,记录左上角为(1,1),右下角为(N,M),现在从(1,1)开始取数,每次只能向下或向右移动一个单位,最终到达(N,M),我们把路径上所有的数相乘,记为C。使C的结果最大已经不能满足我们了,现在我们想让C末尾的零最少。
Ps.11000末尾有3个零,100000100末尾有2个零。

输入

输入文件matrix.in的第一行包含两个正整数N,M表示矩阵大小。
接下来N行每行M个正整数给出整个矩阵。

输出

输出文件名为matrix.out。包含一个整数表示所求最小值。

思路

因为只有在2*5(质数)的情况下才会出现末尾0,所以我们可以把每一个数中的2和5的数量分别找出,分别跑一边最短路(dp)然后输出较小的那个

var
  a,b,c:array[0..1000,0..1000] of longint;
  i,j,k,n,m,s,x,y:longint;
function min<span class="hljs-params">(x,y:longint):longint;
begin
  if x<y then exit(x)
    else exit(y);
end;
begin
  readln(n,m);
  for i:=1 to n do
    for j:=1 to m do
      read(a[i,j]);
  for i:=1 to n do
    for j:=1 to m do
      begin
        x:=a[i,j];
        while x mod 2=0 do
          begin
            inc(b[i,j]);
            x:=x div 2;
          end;
        y:=a[i,j];
        while y mod 5=0 do
          begin
            inc(c[i,j]);
            y:=y div 5;
          end;
      end;

  for i:=2 to n do
    begin
      b[1,i]:=b[1,i-1]+b[1,i];
      c[1,i]:=c[1,i-1]+c[1,i];
    end;
  for i:=2 to m do
    begin
      b[i,1]:=b[i-1,1]+b[i,1];
      c[i,1]:=c[i-1,1]+c[i,1];
    end;

  for i:=2 to n do
    for j:=2 to m do
      begin
        b[i,j]:=b[i,j]+min(b[i-1,j],b[i,j-1]);
        c[i,j]:=c[i,j]+min(c[i-1,j],c[i,j-1]);
      end;
  writeln(min(c[n,m],b[n,m]));
end.