2B The least round way

题目大意:

一个n*n的矩阵,从矩阵的左上角开始,每次移动到下面或者右面,移动到右下角结束。 要求走的路径上的所有数字乘起来,乘积得到的值后面的0最少。
 
#include <iostream>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cstdlib>
using namespace std;
typedef long long LL;
const LL INF = 0xffffff;
const int maxn = 1005;
const LL MOD = 1e9+7;
struct node
{
    int num2, num5;
} dp2[maxn][maxn], dp5[maxn][maxn], a[maxn][maxn];
int K[maxn][maxn], n;

bool HaveZero(int& x,int& y)
{
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=n; j++)
        {
            if(K[i][j] == 0)
            {
                x = i;
                y = j;
                return true;
            }
        }
    }
    return false;
}

void PutPath5(int x,int y)
{
    if(x == 1 && y == 1)
        return;
    if(dp5[x][y].num2 == dp5[x-1][y].num2 + a[x][y].num2 && dp5[x][y].num5 == dp5[x-1][y].num5 + a[x][y].num5)
    {
        PutPath5(x-1, y);
        printf("D");
    }
    else
    {
        PutPath5(x, y-1);
        printf("R");

    }
}

void PutPath2(int x,int y)
{
    if(x == 1 && y == 1)
        return;
    if( dp2[x][y].num2 == dp2[x-1][y].num2 + a[x][y].num2 && dp2[x][y].num5 == dp2[x-1][y].num5 + a[x][y].num5)
    {
        PutPath2(x-1, y);
        printf("D");
    }
    else
    {
        PutPath2(x, y-1);
        printf("R");
    }
}


void PutPath()
{
    int x, y;
    int ans = min( min(dp2[n][n].num2,dp2[n][n].num5) , min(dp5[n][n].num2,dp5[n][n].num5) );
    if( HaveZero(x,y) && ans > 1)
    {
        printf("1\n");
        for(int i=2; i<=x; i++)
            printf("D");
        for(int i=2; i<=y; i++)
            printf("R");
        for(int i=x+1; i<=n; i++)
            printf("D");
        for(int i=y+1; i<=n; i++)
            printf("R");
        return ;
    }
    if( min(dp2[n][n].num2,dp2[n][n].num5) < min(dp5[n][n].num2,dp5[n][n].num5) )
    {
        printf("%d\n", min(dp2[n][n].num2,dp2[n][n].num5));
        PutPath2(n, n);
    }
    else
    {
        printf("%d\n", min(dp5[n][n].num2,dp5[n][n].num5));
        PutPath5(n, n);
    }

}

void Process(int i,int j,int p)
{
    int k = p;
    while(k)
    {
        if(k%2 == 0)
            a[i][j].num2 ++;
        else
            break;
        k /= 2;
    }
    k = p;
    while(k)
    {
        if(k%5 == 0)
            a[i][j].num5 ++;
        else
            break;
        k /= 5;
    }
}
int main()
{
    cin >> n;
    for(int i=1; i<=n; i++)
        for(int j=1; j<=n; j++)
        {
            scanf("%d", &K[i][j]);
            Process(i, j, K[i][j]);
        }

    for(int i=0; i<=n; i++)
    {
        dp2[i][0].num5 = dp2[i][0].num2 = dp2[0][i].num2 = dp2[0][i].num5 = INF;
        dp5[i][0].num5 = dp5[i][0].num2 = dp5[0][i].num2 = dp5[0][i].num5 = INF;
        a[0][i].num2 = a[0][i].num5 = a[i][0].num2 = a[i][0].num5 = INF;
    }
    for(int i=1; i<=n; i++)
        for(int j=1; j<=n; j++)
        {
            dp2[i][j] = a[i][j];
            dp5[i][j] = a[i][j];
            if(dp2[i-1][j].num2 > dp2[i][j-1].num2 && j-1>0)
            {
                dp2[i][j].num2 += dp2[i][j-1].num2 ;
                dp2[i][j].num5 += dp2[i][j-1].num5 ;
            }
            else if(i-1 > 0)
            {
                dp2[i][j].num2 += dp2[i-1][j].num2;
                dp2[i][j].num5 += dp2[i-1][j].num5;
            }

            if(dp5[i-1][j].num5 > dp5[i][j-1].num5 && j-1>0)
            {
                dp5[i][j].num2 += dp5[i][j-1].num2;
                dp5[i][j].num5 += dp5[i][j-1].num5;
            }
            else if(i-1 > 0)
            {
                dp5[i][j].num2 += dp5[i-1][j].num2 ;
                dp5[i][j].num5 += dp5[i-1][j].num5 ;
            }
        }

    PutPath();
    printf("\n");
    return 0;
}

 

posted @ 2015-09-26 22:29  向前走丶不回首  阅读(178)  评论(0编辑  收藏  举报