CF2B The least round way
【题解】
可以发现10的因数除了1和10之外只有2和5了,那么走过的路径上各个数字的2的因数个数之和、5的因数个数之和中较小的一个即是答案。这样的话DP即可。同时需要注意有0的情况,有0的时候有一个答案为1,要和前面求出的答案取较小值。
1 #include<cstdio> 2 #include<algorithm> 3 #define LL long long 4 #define rg register 5 #define N 1010 6 using namespace std; 7 int n,m,px,py,tot,a[N][N],f[N][N],f2[N][N],exp2[N],exp5[N]; 8 bool flag=0; 9 struct rec{ 10 int x,y; 11 }from[N][N],from2[N][N]; 12 char ans[N<<2]; 13 inline int read(){ 14 int k=0,f=1; char c=getchar(); 15 while(c<'0'||c>'9') c=getchar(); 16 while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); 17 return k*f; 18 } 19 int main(){ 20 n=read(); exp2[0]=exp5[0]=1; 21 for(rg int i=1;i<=25;i++) exp2[i]=exp2[i-1]<<1; 22 for(rg int i=1;i<=13;i++) exp5[i]=exp5[i-1]*5; 23 for(rg int i=1;i<=n;i++) 24 for(rg int j=1;j<=n;j++){ 25 a[i][j]=read(); 26 if(!a[i][j]){ 27 flag=1; px=i; py=j; continue; 28 } 29 int tmp=a[i][j]; 30 for(rg int k=25;k;k--) if(tmp%exp2[k]==0) f[i][j]+=k,tmp/=exp2[k]; 31 while(tmp%2==0) f[i][j]++; 32 tmp=a[i][j]; 33 for(rg int k=13;k;k--) if(tmp%exp5[k]==0) f2[i][j]+=k,tmp/=exp5[k]; 34 while(tmp%5==0) f2[i][j]++; 35 // while(tmp%2==0){ 36 // f[i][j]++; 37 // tmp>>=1; 38 // } 39 // tmp=a[i][j]; 40 // while(tmp%5==0){ 41 // f2[i][j]++; 42 // tmp/=5; 43 // } 44 } 45 for(rg int i=2;i<=n;i++) f[i][0]=f[0][i]=f2[i][0]=f2[0][i]=2e9; 46 // f[1][0]=f[0][1]=f2[1][0]=f2[0][1]=0; 47 for(rg int i=1;i<=n;i++) 48 for(rg int j=1;j<=n;j++){ 49 if(f[i-1][j]<f[i][j-1]){ 50 from[i][j]=(rec){i-1,j}; 51 f[i][j]+=f[i-1][j]; 52 } 53 else{ 54 from[i][j]=(rec){i,j-1}; 55 f[i][j]+=f[i][j-1]; 56 } 57 } 58 for(rg int i=1;i<=n;i++) 59 for(rg int j=1;j<=n;j++){ 60 if(f2[i-1][j]<f2[i][j-1]){ 61 from2[i][j]=(rec){i-1,j}; 62 f2[i][j]+=f2[i-1][j]; 63 } 64 else{ 65 from2[i][j]=(rec){i,j-1}; 66 f2[i][j]+=f2[i][j-1]; 67 } 68 } 69 if(flag){ 70 if(min(f[n][n],f2[n][n])>1){ 71 puts("1"); 72 for(rg int i=2;i<=px;i++) putchar('D'); 73 for(rg int i=2;i<=py;i++) putchar('R'); 74 for(rg int i=px+1;i<=n;i++) putchar('D'); 75 for(rg int i=py+1;i<=n;i++) putchar('R'); 76 return 0; 77 } 78 } 79 printf("%d\n",min(f[n][n],f2[n][n])); 80 if(f[n][n]<f2[n][n]){ 81 int nx=n,ny=n; 82 while(1){ 83 int fx=from[nx][ny].x,fy=from[nx][ny].y; 84 if(fx==0||fy==0) break; 85 if(fx<nx) ans[++tot]='D'; 86 else ans[++tot]='R'; 87 nx=fx; ny=fy; 88 if(fx==1&&fy==1) break; 89 } 90 } 91 else{ 92 int nx=n,ny=n; 93 while(1){ 94 int fx=from2[nx][ny].x,fy=from2[nx][ny].y; 95 if(fx==0||fy==0) break; 96 if(fx<nx) ans[++tot]='D'; 97 else ans[++tot]='R'; 98 nx=fx; ny=fy; 99 if(fx==1&&fy==1) break; 100 } 101 } 102 for(rg int i=tot;i;i--) putchar(ans[i]); 103 // puts(""); 104 // for(rg int i=1;i<=n;i++){ 105 // for(rg int j=1;j<=n;j++) printf("[%d %d] ",from2[i][j].x,from2[i][j].y); 106 // puts(""); 107 // } 108 return 0; 109 }