zoukankan      html  css  js  c++  java
  • CF2B The least round way

    (large{题目链接})
    (\)
    (Large extbf{Solution: } large{首先容易想到考虑因子。如果末尾有0,那么一定有一个2对应着一个5。所以只要维护2和5的个数就好。\然后需要特判矩阵中是否有0,如果有,需要和1特判一下。\这道题的输出还真是恶心,不过递归大法好,复杂问题用递归往往能轻易解决。})
    (\)
    (Large extbf{Code: })

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 1e3 + 5;
    
    int n, a[N][N], f[N][N], t[N][N], f_x, f_y;
    
    void read(int &x) {
    	x = 0;
    	char c = getchar();
    	while (!isdigit(c)) c = getchar();
    	while (isdigit(c)) x = x * 10 + c - '0', c = getchar();
    }
    
    int calc(int x, int y, int p) {
    	int ret = 0, cur = a[x][y];
    	for (; cur && !(cur % p); cur /= p) ++ret;
    	return ret;
    }
    
    void print_f(int x, int y) {
    	if (x == 1) { for (int i = 1; i < y; ++i) putchar('R'); return; }
    	if (y == 1) { for (int i = 1; i < x; ++i) putchar('D'); return; }
    	if (f[x - 1][y] + calc(x, y, 5) == f[x][y]) print_f(x - 1, y), putchar('D');
    	else print_f(x, y - 1), putchar('R');
    }
    
    void print_s(int x, int y) {
    	if (x == 1) { for (int i = 1; i < y; ++i) putchar('R'); return; }
    	if (y == 1) { for (int i = 1; i < x; ++i) putchar('D'); return; }
    	if (t[x - 1][y] + calc(x, y, 2) == t[x][y]) print_s(x - 1, y), putchar('D');
    	else print_s(x, y - 1), putchar('R');
    }
    
    void print(int x, int y, int opt) {
    	if (opt == 1) print_f(n, n);
    	else print_s(n, n);
    }
    
    int main() {
    	read(n);
    	for (int i = 1; i <= n; ++i)
    		for (int j = 1; j <= n; ++j) {
    			read(a[i][j]);
    			if (!a[i][j]) f_x = i, f_y = j;
    		}
    	f[1][1] = calc(1, 1, 5), t[1][1] = calc(1, 1, 2);
    	for (int i = 1; i <= n; ++i) {
    		for (int j = 1; j <= n; ++j) {
    			if (i == 1 && j == 1) continue;
    			if (i == 1) { f[i][j] = f[i][j - 1] + calc(i, j, 5), t[i][j] = t[i][j - 1] + calc(i, j, 2); continue; }
    			if (j == 1) { f[i][j] = f[i - 1][j] + calc(i, j, 5), t[i][j] = t[i - 1][j] + calc(i, j, 2); continue; }
    			f[i][j] = min(f[i - 1][j], f[i][j - 1]) + calc(i, j, 5);
    			t[i][j] = min(t[i][j - 1], t[i - 1][j]) + calc(i, j, 2);
    		}
    	}
    	int ans = min(f[n][n], t[n][n]);
    	if (!f_x) printf("%d
    ", ans), print(n, n, (f[n][n] <= t[n][n]));
    	else {
    		if (ans < 1) printf("%d
    ", ans), print(n, n, (f[n][n] <= t[n][n]));
    		else {
    			printf("1
    ");
    			for (int i = 1; i < f_x; ++i) putchar('D');
    			for (int i = 1; i < f_y; ++i) putchar('R');
    			for (int i = f_x; i < n; ++i) putchar('D');
    			for (int i = f_y; i < n; ++i) putchar('R');
    		}
    	}
    	return 0;
    } 
    
  • 相关阅读:
    现代软件工程 第一章 概论 第4题——邓琨
    现代软件工程 第一章 概论 第9题——邓琨
    现代软件工程 第一章 概论 第7题——张星星
    现代软件工程 第一章 概论 第5题——韩婧
    hdu 5821 Ball 贪心(多校)
    hdu 1074 Doing Homework 状压dp
    hdu 1074 Doing Homework 状压dp
    hdu 1069 Monkey and Banana LIS变形
    最长上升子序列的初步学习
    hdu 1024 Max Sum Plus Plus(m段最大子列和)
  • 原文地址:https://www.cnblogs.com/Miraclys/p/12713518.html
Copyright © 2011-2022 走看看