- 编程语:C++
- 单个测试集评测时长限制:3秒
题目描述
有一个方阵 n × n
,由非负整数组成。 你应该找到这样的方式:
- 从矩阵的左上角开始;
- 每个后续单元格都位于当前单元格的右侧或下方;
- 路在右下角的单元格结束。
- 如果我们将一路上的所有数字相乘,结果应该是最不“圆”的。 换句话说,它应该以尽可能少的零结束。
输入格式
第一行包含一个整数 n
(2 ≤ 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;
}