zoukankan      html  css  js  c++  java
  • The least round way

    B. The least round way
    time limit per test2 seconds
    memory limit per test64 megabytes
    inputstandard input
    outputstandard output
    There is a square matrix n × n, consisting of non-negative integer numbers. You should find such a way on it that

    starts in the upper left cell of the matrix;
    each following cell is to the right or down from the current cell;
    the way ends in the bottom right cell.
    Moreover, if we multiply together all the numbers along the way, the result should be the least “round”. In other words, it should end in the least possible number of zeros.

    Input
    The first line contains an integer number n (2 ≤ n ≤ 1000), n is the size of the matrix. Then follow n lines containing the matrix elements (non-negative integer numbers not exceeding 109).

    Output
    In the first line print the least number of trailing zeros. In the second line print the correspondent way itself.

    中文

    B.最小回合方式
    每次测试的时限2秒
    每次测试的内存限制64兆字节
    输入标准输入
    输出标准输出
    有一个由非负整数组成的方阵n  ×  n。您应该在上面找到这样的方法

    从矩阵的左上角单元格开始;
    接下来的每个单元格都位于当前单元格的右侧或下方;
    方式在右下角的单元格中结束。
    此外,如果我们将所有数字相乘,结果应该是最小的“舍入”。换句话说,它应以尽可能少的零结尾。

    输入项
    第一行包含的整数Ñ(2≤  Ñ  ≤1000),Ñ是矩阵的大小。然后跟随n行包含矩阵元素(不超过10 9的非负整数)。

    输出量
    在第一行中,打印最少数量的尾随零。在第二行中打印相应的方式本身。

    例子
    输入项复制
    3
    1 2 3
    4 5 6
    7 8 9
    输出量复制
    0
    DDRR

    两个要求, 第一个就是所走路径上的数字乘起来,0的个数最小, 第二个就是输出的时候要输出一下路径, 参考网上的题解, 若是没有0的个数最小,那么就是一个简单的dp。 而加上这个条件之后, 乘积带0的, 考虑三种情况, 1:路径中含有0 , 那么必然要走这样的,因为此时只有1个零, 最小无疑, 2:路径中含有因子2 ,3 : 路径因子中含有5的个数,因为这两种情况才有可能使乘积构成0, 那么就再考虑一下这两种情况, 其实只单看一种情况就行了, 因为如果两个合起来, 更容易产生尾数含有0的,2 * 5 = 10 , 只需两个因子, 而只考虑含有因子2, 或因子5 , 每一个都非常难以构成一个带0的数, 但是有可能考虑每个因子的时候呢 , 该数同时含有2 和 5 , 所以这种情况我们只需要2 和 5 因子的个数最小就行 , 然后选择路径的时候, 还是三种情况, 若路径中含有0 , 必定选择, 设0的坐标为(x , y) , 那么只需要写成DDDRRRR或者RRRDDDDD 就行了, 然后如果是选择因子2或因子5的那一条,只需看最小值等于哪一种就行了, 然后就递归输出

    #include <iostream>
    #include <cstring>
    using namespace std;
    const int N = 1005 ;
    int n , ans , x , y , a[N][N] , f[N][N] , g[N][N] ; 
    bool zero = 0 ; 
    void go(int x , int y , int p , int q)
    {
    	while(x != p) printf("D") , ++ x ;
    	while(y != q) printf("R") , ++ y ;
    }
    void walk(int h[N][N] , int x , int y)
    {
    	if(x == 1 && y == 1) return ; 
    	if(h[x - 1][y] < h[x][y - 1]) walk(h , x - 1 , y) , printf("D") ;
        else walk(h , x , y - 1) , printf("R") ; 
    }
    int main() 
    { 
    	memset(f , 60 , sizeof f) ;
    	memset(g , 60 , sizeof g) ;
    	f[0][1] = g[0][1] = 0 ;
    	scanf("%d" , &n) ;
    	for(int i = 1 ;i <= n ;i ++)
    	 for(int j = 1 ;j <= n ;j ++)
    	  {
    	  	int u = 0 , v = 0 ;
    	  	scanf("%d" , &a[i][j]) ;
    	  	if(!a[i][j]) zero = 1 , x = i , y = j ;
    	  	if(!a[i][j]) continue ;
    	  	while(a[i][j] % 2 == 0) a[i][j] /= 2 , ++ u ;
    	  	while(a[i][j] % 5 == 0) a[i][j] /= 5 , ++ v ;
    	  	f[i][j] = min(f[i][j - 1] , f[i - 1][j]) + u ;
    	  	g[i][j] = min(g[i][j - 1] , g[i - 1][j]) + v ;
    	  }
    	  ans = min(f[n][n] , g[n][n]) ;
    	  if(zero) ans = min(ans , 1 ) ;
    	  printf("%d
    " , ans) ;
    	  if(ans == f[n][n]) walk(f , n , n) ;
    	  else if(ans == g[n][n]) walk(g , n , n) ;
    	  else
    	   {
    	   	  go(1 , 1, x , y ) ;
    	   	  go(x , y, n , n ) ;
           }
    	return 0 ;
    }
    
    每次做题提醒自己:题目到底有没有读懂,有没有分析彻底、算法够不够贪心、暴力够不够优雅。
  • 相关阅读:
    数据库课程设计心得【3】存储过程的运用
    看BBC研究大脑的科教片中“放松产生灵感”的笔记
    成功干掉“恶心的U盘自动运行病毒免疫目录”!共享方法,让更多的人干掉这东西!
    分享一大堆最新dot net asp.net c# 电子书下载 , 英文原版的。经典中的经典
    SQL学习之 对GROUP BY 和 HAVING 的理解 学习笔记
    关于Theme中.skin与css需要理清的关系
    最近的学习笔记,记录一些通俗易懂的学习类文章。更像是好资料参与索引。
    关于DNN Module开发学习以来的一点总结
    工具发布!QQ空间阅读与备份工具
    被忽视的大道理
  • 原文地址:https://www.cnblogs.com/spnooyseed/p/12870878.html
Copyright © 2011-2022 走看看