2.最少的圆

  • 编程语:C++

  • 单个测试集评测时长限制:3秒

题目描述

有一个方阵 n × n,由非负整数组成。 你应该找到这样的方式:

  1. 从矩阵的左上角开始;
  2. 每个后续单元格都位于当前单元格的右侧或下方;
  3. 路在右下角的单元格结束。
  4. 如果我们将一路上的所有数字相乘,结果应该是最不“圆”的。 换句话说,它应该以尽可能少的零结束。

输入格式

第一行包含一个整数 n2 ≤ n ≤ 1000),n是矩阵的大小。 然后跟随 n 行包含矩阵元素(不超过 109 的非负整数)。

输出格式

在第一行输出最少数量的结尾零。 在第二行输出行走的路线。

输入输出样例

输入1

3 1 2 3 4 5 6 7 8 9

输出1

0 DDRR

#include<cstdio>
#include<iostream>
#include<cstring>
 
using namespace std;
 
const int N=1010;
 
int n;
int f[N][N][2];
 
int main() {
    cin>>n;
 
    int tmp=0;
    for(int i=1;i<=n;i++) {
        for(int j=1;j<=n;j++) {
            int x;
            cin>>x;
            if(!x) {
                tmp=i;
                continue;
            }
            int y=x;
            while(x%2==0) {
                f[i][j][0]++;
                x/=2;
            }
            while(y%5==0) {
                f[i][j][1]++;
                y/=5;
            }
        }
    }
 
    for(int i=2;i<=n;i++) {
        f[i][1][0]+=f[i-1][1][0];
        f[i][1][1]+=f[i-1][1][1];
        f[1][i][0]+=f[1][i-1][0];
        f[1][i][1]+=f[1][i-1][1];
    }
 
    for(int i=2;i<=n;i++) {
        for(int j=2;j<=n;j++) {
            f[i][j][0]+=min(f[i-1][j][0],f[i][j-1][0]);
            f[i][j][1]+=min(f[i-1][j][1],f[i][j-1][1]);
        }
    }
    int res=0;
    if(f[n][n][0]>f[n][n][1]) res=1;
 
    if(tmp&&f[n][n][res]>0) {
        cout<<1<<endl;
        for(int i=1;i<tmp;i++) cout<<"D";
        for(int j=1;j<n;j++) cout<<"R";
        for(int i=tmp;i<n;i++) cout<<"D";
        cout<<endl;
        return 0;
    }
 
    string ans="";
    int i=n,j=n;
    while(i>1&&j>1) {
        if(f[i][j-1][res]>f[i-1][j][res]) ans+='D',i--;
        else ans+='R',j--;
        if(i==1) {
            for(int cnt=1;cnt<j;cnt++) ans+='R';
            break;
        }
        if(j==1) {
            for(int cnt=1;cnt<i;cnt++) ans+='D';
            break;
        }
    }
    int si=ans.size();
    cout<<f[n][n][res]<<endl;
    for(int cnt=si-1;cnt>=0;cnt--) cout<<ans[cnt];
    cout<<endl;
    return 0;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值