Codeforces Beta Round #2 B. The least round way

这个2B题还好~~

题目大意:

给出一个矩阵,从左上走到右下,只能往右或下走。路径中每个格子有一个数,这些数相乘得出一个数。

求这个数末尾零最少的一条路径。

解题思路:

找出一条路径,乘积得数中素因子2的个数最少,再找出一个素因子5最少, 比较两个输出最小的。

有意外情况就是有数为零。这种情况把零当成10跑一遍,如果素因子最少为0,输出路径,如果不是,输出经过零的路径。

下面是代码:

#include <set>
#include <map>
#include <queue>
#include <math.h>
#include <vector>
#include <string>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <cctype>
#include <algorithm>

#define eps 1e-10
#define pi acos(-1.0)
#define inf 107374182
#define inf64 1152921504606846976
#define lc l,m,tr<<1
#define rc m + 1,r,tr<<1|1
#define zero(a) fabs(a)<eps
#define iabs(x)  ((x) > 0 ? (x) : -(x))
#define clear1(A, X, SIZE) memset(A, X, sizeof(A[0]) * (min(SIZE,sizeof(A))))
#define clearall(A, X) memset(A, X, sizeof(A))
#define memcopy1(A , X, SIZE) memcpy(A , X ,sizeof(X[0])*(SIZE))
#define memcopyall(A, X) memcpy(A , X ,sizeof(X))
#define max( x, y )  ( ((x) > (y)) ? (x) : (y) )
#define min( x, y )  ( ((x) < (y)) ? (x) : (y) )

using namespace std;

int dp[1005][1005][2];
int cnt[1005][1005][2];
int pre[1005][1005][2];

void output(int x,int y,int num)
{
    if(x==0&&y==0)return ;
    if(pre[x][y][num]==0)
    {
        output(x,y-1,num);
        printf("R");
    }
    else
    {
        output(x-1,y,num);
        printf("D");
    }
}

int main()
{
    int input,n,x=-1,y=-1;
    scanf("%d",&n);
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<n; j++)
        {
            scanf("%d",&input);
            if(input==0)
            {
                cnt[i][j][0]=1;
                cnt[i][j][1]=1;
                x=i;
                y=j;
                continue;
            }
            cnt[i][j][0]=0;
            while(input%2==0)
            {
                cnt[i][j][0]++;
                input/=2;
            }
            cnt[i][j][1]=0;
            while(input%5==0)
            {
                cnt[i][j][1]++;
                input/=5;
            }
        }
    }
    clearall(pre,-1);
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<n; j++)
        {
            if(i==0)
            {
                if(j==0)
                {
                    dp[0][0][0]=cnt[0][0][0];
                    dp[0][0][1]=cnt[0][0][1];
                }
                else
                {
                    dp[0][j][0]=cnt[0][j][0]+dp[0][j-1][0];
                    dp[0][j][1]=cnt[0][j][1]+dp[0][j-1][1];
                    pre[0][j][0]=0;
                    pre[0][j][1]=0;
                }
            }
            else if(j==0)
            {
                dp[i][0][0]=dp[i-1][0][0]+cnt[i][0][0];
                dp[i][0][1]=dp[i-1][0][1]+cnt[i][0][1];
                pre[i][0][0]=1;
                pre[i][0][1]=1;
            }
            else
            {
                if(dp[i][j-1][0]>dp[i-1][j][0])
                {
                    dp[i][j][0]=dp[i-1][j][0]+cnt[i][j][0];
                    pre[i][j][0]=1;
                }
                else
                {
                    dp[i][j][0]=dp[i][j-1][0]+cnt[i][j][0];
                    pre[i][j][0]=0;
                }
                if(dp[i][j-1][1]>dp[i-1][j][1])
                {
                    dp[i][j][1]=dp[i-1][j][1]+cnt[i][j][1];
                    pre[i][j][1]=1;
                }
                else
                {
                    dp[i][j][1]=dp[i][j-1][1]+cnt[i][j][1];
                    pre[i][j][1]=0;
                }
            }
        }
    }
    if(x!=-1)
    {
        if(min(dp[n-1][n-1][0],dp[n-1][n-1][1])==0)
        {
            printf("0\n");
            if(dp[n-1][n-1][0]==0)output(n-1,n-1,0);
            else output(n-1,n-1,1);
        }
        else
        {
            printf("1\n");
            for(int i=0;i<n-1;i++)
            {
                if(i==x)
                {
                    for(int j=0;j<n-1;j++)
                    {
                        printf("R");
                    }
                }
                printf("D");
            }
        }
    }
    else
    {
        printf("%d\n",min(dp[n-1][n-1][0],dp[n-1][n-1][1]));
        if(dp[n-1][n-1][0]<dp[n-1][n-1][1])
        {
            output(n-1,n-1,0);
        }
        else output(n-1,n-1,1);
    }
    return 0;
}
时间: 2024-10-29 11:17:38

Codeforces Beta Round #2 B. The least round way的相关文章

Codeforces Beta Round #91 (Div. 1 Only) E. Lucky Array

E. Lucky Array Petya loves lucky numbers. Everybody knows that lucky numbers are positive integers whose decimal representation contains only the lucky digits 4 and 7. For example, numbers 47, 744, 4 are lucky and 5, 17, 467are not. Petya has an arra

Codeforces Beta Round #85 (Div. 1 Only) C (状态压缩或是数学?)

C. Petya and Spiders Little Petya loves training spiders. Petya has a board n × m in size. Each cell of the board initially has a spider sitting on it. After one second Petya chooses a certain action for each spider, and all of them humbly perform it

CodeForces Beta Round #1

Codeforces Beta Round #1 A. Theatre Square [题意]一个n*m的矩形广场,用a*a的方形石板铺设,问最少需要多少块石板能铺满广场. [思路]水题,从n方向来看能能够铺设ceil(n/a)块,从m方向来看能能够铺设ceil(m/a)块,总共有ceil(n/a)*ceil(m/a)块. 1 /* 2 ** CodeForces 1A Theatre Square 3 ** Created by Rayn @@ 2014/05/18 4 */ 5 #inclu

暴力/DP Codeforces Beta Round #22 (Div. 2 Only) B. Bargaining Table

题目传送门 1 /* 2 题意:求最大矩形(全0)的面积 3 暴力/dp:每对一个0查看它左下的最大矩形面积,更新ans 4 注意:是字符串,没用空格,好事多磨,WA了多少次才发现:( 5 详细解释:http://www.cnblogs.com/cszlg/p/3217478.html 6 */ 7 #include <cstdio> 8 #include <algorithm> 9 #include <cstring> 10 #include <cmath>

Codeforces Beta Round #6 (Div. 2 Only) B. President&#39;s Office

题目大意 给出一个n*m的矩阵 ,描述桌子的布局.总统的桌子和他的副手的桌子相邻,每一个人的桌子有它独有的颜色.问总统有多少个副手. 解题思路 搜出总统的桌子在矩阵中的边界后判断边界外的其它颜色桌子的数量. 题目代码 #include <set> #include <map> #include <queue> #include <math.h> #include <vector> #include <string> #include

图论/暴力 Codeforces Beta Round #94 (Div. 2 Only) B. Students and Shoelaces

题目传送门 1 /* 2 图论/暴力:这是个连通的问题,每一次把所有度数为1的砍掉,把连接的点再砍掉,总之很神奇,不懂:) 3 */ 4 #include <cstdio> 5 #include <cstring> 6 #include <algorithm> 7 #include <cmath> 8 using namespace std; 9 10 const int MAXN = 1e2 + 10; 11 const int INF = 0x3f3f3

Codeforces Beta Round #1 B. Spreadsheets

Codeblocks坏掉了,我不知道该怎么修,只能过两天重装系统了. 没办法.这个题是用Java写的,代码风格不好不要骂我~~ 题目大意: Excel表格那种坐标系统,和正常的坐标系统.用代码实现转换. 就是模拟题啊,代码量比较小. 下面是代码: import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner cin = new Scanner(System.in); i

Codeforces Beta Round #1 C. Ancient Berland Circus

果然Java还是不靠谱啊,一个NaN把我整了半天~~ 题目大意: 有一个正多边形,给出任意三个顶点的坐标,求这个正多边形的最小面积. 解题思路: 首先要知道这三个顶点组成的三角形的外接圆一定是这个正多边形的外接圆. 用过计算出三角形的三边长,可以计算出三角型面积,进而推出外接圆半径. 可以得到三个圆心角,找出最大公约数,那就是最大角度. 就可以计算出多边形面积了~~ 下面是代码: import java.text.DecimalFormat; import java.util.Scanner;

codeforces Beta Round #19 D. Point (线段树 + set)

题目大意: 对平面上的点进行操作. add x y 在 (x,y )上加一个点. remove x y 移除 (x,y)上的点. find x y 求出在(x,y)右上角离他最近的点,优先级是靠左,靠下. 思路分析: find 操作 比较麻烦. 要保证x大的同时还要确保x最小,而且该x上还要有点. 这样要找大的时候要小的,就是在线段树上选择性的进入左子树还是右子树. 所以核心就是,用set维护叶子节点. 然后查找的时候去叶子节点找,如果这个叶子节点有蛮子的 x y  就输出,否则回溯去另外一个子

Codeforces Beta Round #12 D. Ball (线段树)

题目大意: n个女性中,如果有一个女性的三维比这个女性的三维都大,这个女性就要自杀.问要自杀多少个. 思路分析: 先按照第一维排序. 然后离散化第二维,用第二维的下标建树,树上的值是第三维,更新的时候取最大值. 注意是按照第一维度从大到小进入线段树. 而且还要严格递增. 所以处理第一维度比较大小的时候要分开处理,要把相同的先判断,再更新入树. 那么如何判断这个女性是否自杀. 首先,你知道第一维度是从大到小的,所以先进树了的节点的第一维度一定更大. 再次,我们考虑第二维度,我们去树上第二维度下标大