JZOJ8.11(C组)【NOIP2011模拟9.1】方格取数 (Standard IO)

    xiaoxiao2025-01-08  12

    题目:

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

    分析:

    一开始用了暴力DFS才三十分。

    由题意可以得我们要使路径上的25的因子个数尽量少,可以枚举两次,用min1记录最少2的路径和用min2记录最少5的路径,最后结果min(min1,min2)

    附上代码:

    const   maxn=1000; var   n,m:longint;   two,five,f:array [0..maxn,0..maxn] of longint; procedure init; var   i,j,k,temp:longint; begin   readln(n,m);   for i:=1 to n do     for j:=1 to m do       begin         k:=0;         read(temp);         while temp mod 2=0 do           begin             inc(k);             temp:=temp div 2;           end;         two[i,j]:=k;         k:=0;         while temp mod 5=0 do           begin             inc(k);             temp:=temp div 5;           end;         five[i,j]:=k;      end; end; function min(x,y:longint):longint; begin   if x<y then     exit(x);   exit(y); end; procedure main; var   i,j,tott,totf:longint; begin   for i:=1 to n do     for j:=1 to m do       if i=1 then         f[i,j]:=f[i,j-1]+two[i,j]       else         if j=1 then           f[i,j]:=f[i-1,j]+two[i,j]         else           f[i,j]:=min(f[i-1,j],f[i,j-1])+two[i,j];   tott:=f[n,m];   fillchar(f,sizeof(f),0);   for i:=1 to n do     for j:=1 to m do       if i=1 then         f[i,j]:=f[i,j-1]+five[i,j]       else         if j=1 then           f[i,j]:=f[i-1,j]+five[i,j]         else           f[i,j]:=min(f[i-1,j],f[i,j-1])+five[i,j];   totf:=f[n,m];   write(min(tott,totf)); end; begin   init;   main; end.

    转载请注明原文地址: https://ju.6miu.com/read-1295257.html
    最新回复(0)