codeforces 2B-The least round way

题意

n阶数字矩阵,从左上第一个数,到右下最后一个数,只能向右或向下走,经过的数字进行相乘,求最后结果尾数为0最少的路径

题解

  1. 若要相乘之后结果有0有两种情况
    1. 相乘的数中包含2和5,即要求经过2或5最少的路径
    2. 经过0时,无论其他数为多少,最后都为1个0,因此要记录好0的位置,此处要特判
  2. 若相乘之后没有0,无疑是最好的

利用动态规划,通过题意写出转移方程:

D[r,c] = min(D[r-1,c],D[r,c-1]) + A[r][c]

f[x][y][z]表示在x行y列2和5的个数:
f[x][y][0]:表示x行y列的2的个数
f[x][y][1]:表示x行y列的2的个数
g[x][y][z]表示在选择数字z时,x行y列处是向下还是向右,1是向下,0是向右

知识点

  • 路径的输出,通过递归的方式进行回溯输出
    若图为此,想从s[1][1]走到s[4][4]的路径是通过从s[4][4]倒推回s[1][1]的:
    s[4][4]为1,则输出D,即走到s[3][4]
    s[3][4]为1,则输出D,即走到s[2][4]
    s[2][4]为0,则输出R,即走到s[2][3]
    s[2][3]为0,则输出R,即走到s[2][2]
    s[2][2]为1,则输出D,即走到s[1][2]
    s[1][2]为0,则输出R,即走到s[1][1]
    s[1][1]为1,没啥用,直接return了
int s[5][5]={
0,0,0,0,0,
0,1,0,0,0,
0,0,1,0,0,
0,0,0,0,1,
0,0,0,0,1,
};
void func(int x, int y){
    if(x==1 &&y==1) return;
    if(s[x][y]){
        func(x-1,y); putchar('D');
    }
    else{    
        func(x, y-1); putchar('R');
    }
}

func(4,4);  //RDRRDR

代码

#include <cstdio>
#include <cstring>
#include <cmath>
#define inf 0x7fffffff
using namespace std;

int f[1001][1001][2],n,x,t;
char g[1001][1001][2];

void print(int x,int y){
    if(x==1&&y==1)
        return ;
    if(g[x][y][t])
        print(x-1,y),putchar('D');
    else
        print(x,y-1),putchar('R');
}

int main(void){
    scanf("%d",&n);
    memset(f,0,sizeof(f));
    for(int i=2;i<=n;++i)
        f[0][i][0]=f[0][i][1]=f[i][0][0]=f[i][0][1]=inf;
    for(int i=1;i<=n;++i){
        for(int j=1;j<=n;++j){
            scanf("%d",&t);
            if(!t) x=i;     //判断0在第x行
            else{
                while(t%2==0) ++f[i][j][0],t/=2;
                while(t%5==0) ++f[i][j][1],t/=5;
            }
            for(int k=0;k<2;k++)
                if((g[i][j][k]=f[i-1][j][k]<f[i][j-1][k]))
                    f[i][j][k]+=f[i-1][j][k];
                else f[i][j][k]+=f[i][j-1][k];
        }
    }
    t=f[n][n][1]<f[n][n][0];
    if(x&&f[n][n][t]>1){        //有0的那行特判
        puts("1");
        for(int i=2;i<=x;i++) putchar('D');
        for(int i=2;i<=n;i++) putchar('R');
        for(int i=x+1;i<=n;i++) putchar('D');
        puts("");
    }
    else
        printf("%d\n",f[n][n][t]),print(n,n);
    puts("");
}
发布了64 篇原创文章 · 获赞 3 · 访问量 6228

猜你喜欢

转载自blog.csdn.net/qazsatan/article/details/102847181