【学习笔记】CF2B The least round way 题解

题目传送门

正解

思路

  • 显然,末尾 0 的个数仅和路径中各数 2 和 5 的因子的最小值有关,因为只有 2 和 5 搭配才能产生 0 。

  • 当然,如果走了一个 0 ,那么无论如何,都有且仅有一个 0 !

  • 所以,分别对 2 和 5 做一遍 DP,取最小值即可。

  • 当然,如果有 0 ,答案最大肯定就只能是 1 辣!

  • 那么,怎么输出路径呢?

  • 比较简单,如果选择走 0 的话,直接按照如下路径走即可:

【学习笔记】CF2B The least round way 题解

  • 反之,在 DP 的时候记录一下前驱,然后倒推并输出即可。

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int MAXN(1011);
typedef long long ll;
ll n;
ll qwt[MAXN][MAXN],qwf[MAXN][MAXN];
bool QWQ[MAXN][MAXN];
ll det[MAXN][MAXN],def[MAXN][MAXN],zy,xxxx;
bool qqt[MAXN][MAXN],qqf[MAXN][MAXN];
bool fnzer;
char stk[MAXN];
int cnt;
inline char giegie(bool fk){
	return fk?'D':'R';
}
int main(){
	scanf("%lld",&n);
	for(int i=1;i<=n;++i){
		for(int j=1;j<=n;++j){
			ll qwqaq,qwqwq;scanf("%lld",&qwqaq);
			QWQ[i][j]=qwqaq;
			qwqwq=qwqaq;
			while((!(qwqaq%2))&&qwqaq){qwt[i][j]++,qwqaq/=2;}
			while((!(qwqwq%5))&&qwqwq){qwf[i][j]++,qwqwq/=5;}
//			printf("%d %d %d %d\n",i,j,qwt[i][j],qwf[i][j]);
			if(!QWQ[i][j]) zy=j,fnzer=true;
		}
	}	
	for(register int i=0;i<=n+5;++i)
		for(register int j=0;j<=n+5;++j)
			det[i][j]=def[i][j]=1919810;
	det[0][1]=det[1][0]=def[0][1]=def[1][0]=0;
	for(int i=1;i<=n;++i){
		for(int j=1;j<=n;++j){
			if(!QWQ[i][j]) continue;
			det[i][j]=min(det[i-1][j],det[i][j-1])+qwt[i][j];
			qqt[i][j]=(det[i-1][j]<=det[i][j-1]);
			def[i][j]=min(def[i-1][j],def[i][j-1])+qwf[i][j];
			qqf[i][j]=(def[i-1][j]<=def[i][j-1]);
		}
	}
	if((det[n][n]==1919810)||(fnzer&&(min(det[n][n],def[n][n]))>1)){
		printf("1\n");
		for(int i=2;i<=zy;++i) printf("R");
		for(int i=2;i<=n;++i) printf("D");
		for(register int i=zy+1;i<=n;++i) printf("R");
	}
	else{
		printf("%lld\n",min(det[n][n],def[n][n]));
		ll xxx=n,yyy=n;cnt=0;
		if(det[n][n]<=def[n][n]){
			while((xxx>1)||(yyy>1)){
//				printf("%d %d\n",xxx,yyy);
				stk[++cnt]=giegie(qqt[xxx][yyy]);
				xxxx=xxx;
				xxx-=qqt[xxx][yyy];
				yyy-=(!qqt[xxxx][yyy]);
			}
		}
		else{
//			printf("here!");
			while((xxx>1)||(yyy>1)){
//				printf("%d %d\n",xxx,yyy);
				stk[++cnt]=giegie(qqf[xxx][yyy]);
//				printf("qwqwqaq:%d\n",cnt);
				xxxx=xxx;
				xxx-=qqf[xxx][yyy];
				yyy-=(!qqf[xxxx][yyy]);
			}
		}
//		printf("fkfkfk %d\n",cnt);
		while(cnt>0){
//			printf("nonono\n");
			printf("%c",stk[cnt]);
			--cnt;
		}
	}
	return 0;
}
/*
5
1 1 1 1 0
0 10 0 1 0
0 1 1 1 0
10 1 10 100000 10
0 1 1 1 1
*/
上一篇:Vue3学习(十)之 页面、菜单、路由的使用


下一篇:B - Young Explorers(Codeforces Round #737 (Div. 2))