CF2B The least round way

CF2B The least round way

message1:

脚造的垃圾hack数据:

3

0 1 1

1 1 1

1 1 1

ans:

1

DDRR

数据2:

3

0 1 1

1 1 0

1 1 1

ans:

1

DDRR

dp

0由2×5组成

预处理每个位置2因子、5因子个数

f[i][j][k]表示dp到(i,j),k因子至少有几个

输出路径只要倒着dfs一遍即可

代码:

#include<bits/stdc++.h>
using namespace std;
int n;
int s[1005][1005][2]={0};
int g[1005][1005][2]={0};//-1:no 0:up 1:left
bool flag=0;
int xx,yy;
void get(int i,int j,int x){
    int cnt1=0,cnt2=0;
    while(x%2==0) x/=2,cnt1++;
    while(x%5==0) x/=5,cnt2++;
    s[i][j][0]=cnt1,s[i][j][1]=cnt2;
}
void print(int x,int y,int k,int F){
    if(x==1&&y==1) ;
    else if(x==1) print(x,y-1,k,0);
    else if(y==1) print(x-1,y,k,1);
    else{
        if(g[x][y][k]==g[x][y-1][k]+s[x][y][k]) print(x,y-1,k,0);
        else print(x-1,y,k,1);
    }
    if(F==0) printf("R");
    else if(F==1) printf("D");
}
int main(){
    //freopen("a.in","r",stdin);
    //freopen("a.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            int x;
            scanf("%d",&x);
            if(x==0){
                flag=1;
                s[i][j][0]++,s[i][j][1]++;
                xx=i,yy=j;
            }
            else{
                get(i,j,x);
            }
        }
    }
    memset(g,127,sizeof(g));
    g[1][1][0]=s[1][1][0];
    g[1][1][1]=s[1][1][1];
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(i==1&&j==1) continue;
            int a,b;
            a=g[i-1][j][0],b=g[i][j-1][0];
            if(a<b){
                g[i][j][0]=a+s[i][j][0];
            }
            else{
                g[i][j][0]=b+s[i][j][0];
            }
            a=g[i-1][j][1],b=g[i][j-1][1];
            if(a<b){
                g[i][j][1]=a+s[i][j][1];
            }
            else{
                g[i][j][1]=b+s[i][j][1];
            }
        }
    }
    if(min(g[n][n][0],g[n][n][1])>1&&flag){
        printf("1\n");
        for(int i=1;i<xx;i++) printf("D");
        for(int i=1;i<yy;i++) printf("R");
        for(int i=xx+1;i<=n;i++) printf("D");
        for(int i=yy+1;i<=n;i++) printf("R");
        return 0;
    }
    printf("%d\n",min(g[n][n][0],g[n][n][1]));
    if(g[n][n][0]<g[n][n][1]) print(n,n,0,233);
    else print(n,n,1,233);
    return 0;
}

但是这份代码还是会被前面的hack数据给hack掉

原文地址:https://www.cnblogs.com/QYJ060604/p/11426844.html

时间: 2024-10-13 20:07:32

CF2B The least round way的相关文章

CF2B The least round way 题解

都是泪呀...↑ 题目传送门 题意(直接复制了QWQ) 题目描述 给定由非负整数组成的\(n \times n\)的正方形矩阵,你需要寻找一条路径: 以左上角为起点, 每次只能向右或向下走, 以右下角为终点 并且,如果我们把沿路遇到的数进行相乘,积应当是最小"round",换句话说,应当以最小数目的0的结尾. 输入格式 第一行包含一个整数 \((2 \leq n \leq 1000)\),\(n\)为矩阵的规模,接下来的\(n\)行包含矩阵的元素(不超过\(10^9\)的非负整数).

[CF2B] The least round way - dp

给定由非负整数组成的n×n 的正方形矩阵,你需要寻找一条路径: 以左上角为起点 每次只能向右或向下走 以右下角为终点 并且,如果我们把沿路遇到的数进行相乘,积应当是最小"round",换句话说,应当以最小数目的0的结尾. Solution 考虑到最终答案只取决于 \(2,5\) 因子数中最小的那一个,所以可以拆开考虑,然后就是一个朴素的最小和路径dp了 注意如果原矩阵中包含零,答案要和 \(1\) 取 min 一下 #include <bits/stdc++.h> usin

解题报告: CF2B

题目链接:CF2B The least round way 显然需要 \(dp\) 解决. 第一个思路:用 \(dp_{i}{j}\)代表第 \(i\) 行第 \(j\) 列最小的后缀 \(0\) 数,不幸的是,他被 hack 了. 考虑 \(10\)的形成,贡献只来自于 \(2\) 和 \(5\) 这个因数. 我们容易想到最小化 \(\min\{\sum a_i,\sum b_i\}\). ps:\(\sum a_i\) 代表路径中数含有因子 \(2\) 的数量,\(\sum b_i\) 代表

Educational Codeforces Round 21 G. Anthem of Berland(dp+kmp)

题目链接:Educational Codeforces Round 21 G. Anthem of Berland 题意: 给你两个字符串,第一个字符串包含问号,问号可以变成任意字符串. 问你第一个字符串最多包含多少个第二个字符串. 题解: 考虑dp[i][j],表示当前考虑到第一个串的第i位,已经匹配到第二个字符串的第j位. 这样的话复杂度为26*n*m*O(fail). fail可以用kmp进行预处理,将26个字母全部处理出来,这样复杂度就变成了26*n*m. 状态转移看代码(就是一个kmp

SnackDown Online Pre-elimination round A

1. 应该n是偶数,就行吧.应该判断1个人,只能出现一次吧. 1 #include<bits/stdc++.h> 2 #define pb push_back 3 typedef long long ll; 4 using namespace std; 5 typedef pair<int, int> pii; 6 const int maxn = 1e3 + 10; 7 8 void yes() {cout << "yes" << en

code force 2B The least round way

There is a square matrix n?×?n, consisting of non-negative integer numbers. You should find such a way on it that starts in the upper left cell of the matrix; each following cell is to the right or down from the current cell; the way ends in the bott

MySQL中ROUND和TRUNCATE的区别

1.ROUND可以进行四舍五入,按照对应的位数 2.TRUNCATE直接按照位数截取,不四舍五入 实例: SELECT ROUND(RAND(),4),TRUNCATE(RAND(),4); 版权声明:本文为博主原创文章,未经博主允许不得转载.

Codeforces 837D Round Subset(背包)

题目链接  Round Subset 题意  在n个数中选择k个数,求这k个数乘积末尾0个数的最大值. 首先我们预处理出每个数5的因子个数c[i]和2的因子个数d[i] 然后就可以背包了. 设f[i][j]为选i个数,5的因子总和为j时,2的因子总和的最大值. 则状态转移方程为 $f[i][j] = max(f[i - 1][j - c[k]] + d[k])$ 注意边界条件 时间复杂度$O(5200nk)$ #include <bits/stdc++.h> using namespace s

poj3252 Round Numbers

Round Numbers POJ - 3252 题目大意: 输入两个十进制正整数a和b,求闭区间[a,b]内有多少个Round Number? 所谓的Round Number就是一个把十进制数转换成一个无符号二进制数,若该二进制数中0的个数大于等于1的个数,则它就是一个Round Number. 注意 转换所得的二进制数,最高位必然是1,最高位前不允许有0 /* 以前用的组合数学,听说dalao也用数位dp做,我也来一下 */ #include<iostream> #include<c