zoukankan      html  css  js  c++  java
  • codeforces 2B The least round way(DP+数学)

    The least round way

    题目链接:http://codeforces.com/contest/2/problem/B

        ——每天在线,欢迎留言谈论。PS.本题有什么想法、建议、疑问 欢迎留言!!

    题目大意:

    ①第一行给你一个n,表示接下来将给你一个n阶方阵的数据

    ②要求你从左上方出发到右下方,路径上所有数字乘积 的末尾0的个数最少

    ③输出最少0的个数,并输出路径

    PS:①每次只能向右或向走 ②D表示向下走,R表示向右 ③0乘任何数的结果 末尾都是一个0;

    知识点:

    ①多个数字相乘,末尾0个个数为:每个乘数分解质因数后 min(2的个数,5的个数);

    ②基本的DP(动态规划)- 本题dp出2、5 个数的最小值。

    思路:

    ①末尾0个个数只跟线路上2、5的个数有关,所以读入数据时只要保存 2、5的个数即可

    ②通过dp,分别找出 2个数最小的路和5个数最小的路。

    ③那么结果有情况:下面用num2、num5表示 2、5最小的个数

    ④由于0比较特殊 所以需要考虑 (①把他当作10②记入第一个0的位子)(自己想为什么可以喽。。哈哈)

    Ⅰ. num2、num5 当中全为0或其中一个为0 

      代表有某条路乘级末尾无0;直接输出。

    Ⅱ . 如果输入数据中有0,那么0乘任何数末尾都是一个0,直接输出带0的一条路即可

    Ⅲ . 其他无0情况 输出 min(num2,num5) 那条路就可以了!

    感想:

    这题的难点在于 对多个数相乘末尾0的个数性质的了解 和 对有0的处理 。

    o.o 这个题要考虑的细节确实有点多,需要慢慢考虑。

    o.o 输出的部分我既然写了40行代码。。。

    PS.本题有什么想法、建议、疑问 欢迎留言!!

    AC代码:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 using namespace std;
      6 const int MAXN=1005;
      7 const int inf=0x3f3f3f3f;
      8 struct node
      9 {
     10     int times[2];
     11     node(int a=0,int b=0){times[0]=a;times[1]=b;}
     12 };
     13 //----这里有几个全局变量↓
     14 node matrix[MAXN][MAXN];int n;//记录每个点的质因子2 5的个数
     15 bool isfind[MAXN][MAXN],ishavezero=false;//dp 时 记忆化搜索用
     16 int zeroy=0;
     17 //----这里有几个全局变量↑
     18 int get_num(int num,int y)
     19 {//获取数字num 质因子中 y 的个数
     20     int temp=0;
     21     while(num!=0&&num%y==0)
     22     {
     23         temp++;
     24         num/=y;
     25     }
     26     return temp;
     27 }
     28 int dp(int y,int i=1,int j=1)//动态规划:通过记忆搜索的方法
     29 {//y用来表示dp的是2还是5  y=0为2  y=1为5  ps.node结构体中int times[2];节省重复代码
     30     if(isfind[i][j])//是否已搜索过
     31         return matrix[i][j].times[y];
     32     isfind[i][j]=true;
     33     if(i==n&&j==n)//开始边界处理
     34         {return matrix[i][j].times[y];}
     35     else if(i==n)
     36         return matrix[i][j].times[y]=matrix[i][j].times[y]+dp(y,i,j+1);
     37     else if(j==n)
     38         return matrix[i][j].times[y]=matrix[i][j].times[y]+dp(y,i+1,j);
     39     //中间一般情况
     40     return matrix[i][j].times[y]=matrix[i][j].times[y]+min(dp(y,i+1,j),dp(y,i,j+1));
     41 }
     42 void putout()
     43 {//开始输出答案  ps.输出答案 写了40行的代码。。。。我也是lj
     44     int y=0;
     45     if(matrix[1][1].times[0]>matrix[1][1].times[1])
     46         y=1;
     47     if(ishavezero&&matrix[1][1].times[y]>0)
     48     {
     49         cout<<"1"<<endl;
     50         for(int i=1;i<n;)
     51         {
     52             if(i==zeroy)
     53             {
     54                 for(int j=1;j<n;j++)
     55                     cout<<"D";
     56             }
     57             cout<<"R";i++;
     58         }
     59         return ;
     60     }
     61         cout<<matrix[1][1].times[y]<<endl;
     62         for(int i=1;i<=n;)
     63             for(int j=1;j<=n;)
     64         {
     65             if(j==n&&i==n)return ;
     66             else if(j==n)
     67             {for(int t=i;t<n;t++)
     68                     cout<<"D";return ;
     69             }
     70             else if(i==n)
     71             {for(int t=j;t<n;t++)
     72                     cout<<"R";return ;
     73             }
     74             if(matrix[i+1][j].times[y]<=matrix[i][j+1].times[y])
     75             {
     76                 cout<<"D";
     77                 i++;
     78             }
     79             else
     80             {cout<<"R";j++;}
     81         }
     82 cout<<endl;
     83 }
     84 int main()
     85 {
     86     int temp;//接受输入的数
     87     cin>>n;
     88     for(int i=1;i<=n;i++)
     89         for(int j=1;j<=n;j++)
     90     {
     91         cin>>temp;
     92         if(!temp)
     93             {temp=10;if(!ishavezero){ishavezero=true;zeroy=j;}}
     94         matrix[i][j]=node(get_num(temp,2),get_num(temp,5));
     95     }
     96     memset(isfind,0,sizeof(isfind));//out();
     97     dp(0);
     98     memset(isfind,0,sizeof(isfind));
     99     dp(1);//out();
    100     putout();
    101     return 0;
    102 }

     2017-05-12 13:21:50

  • 相关阅读:
    AngularJS:实现动态添加输入控件功能
    Openfire:XMPP的几种消息类型
    Openfire:重新配置openfire
    Clojure:日期操作方法
    Openfire:通过Servlet群发消息
    Openfire:访问Servlet时绕开Openfire的身份验证
    Clojure:解决selmer模板不刷新的问题
    Intellij Idea 13:运行Clojure的repl环境
    MVC.Net 5:允许保存和输出Html内容
    BAE Flask UEditor 使用七牛云
  • 原文地址:https://www.cnblogs.com/Twobox/p/6845125.html
Copyright © 2011-2022 走看看