• Codeforces Round #689 (Div. 2, based on Zed Code Competition)B. Find the Spruce(dp + 重复利用)


    B. Find the Spruce

    题意

    给你一个n行m列由*或者.组成的图形,一个图形高度为k时当且仅当满足(1 leq i leq k)时,第(x + i - 1)行必须满足在区间([y - i + 1, y +i-1])全部都是'*'

    思路

    暴力解决方法

    我们暴力判断当前行是否满足,如果满足我们继续将k加大然后继续向下判断,判断k的整个过程具有连续性,比如说当(k=3)时会重复判断(k=2)时的情况,所以直接继续判断即可。如果不满足则跳出。

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 2e5 + 100;
    typedef long long LL;
    //#define int long long 
     
    char str[505][505];
    int sum[505][505];
    int n, m;
    
    void solve() {
    	scanf("%d%d", &n, &m);
    	for (int i = 1; i <= n; ++i) {
    		getchar();
    		for (int j = 1; j <= m; ++j) {
    			scanf("%c", &str[i][j]);
    			if (str[i][j] == '*') {
    				sum[i][j] = sum[i][j - 1]  + 1;
    			}else sum[i][j] = sum[i][j - 1];
    		}
    	}
    	LL ans = 0;
    	for (int i = 1; i <= n; ++i) {
    		for (int j = 1; j <= m; ++j) {
    			for (int k = 1;; ++k) {
    				  int l = i + k - 1;
    				  int l1 = j - k + 1, r1 = j + k - 1;
    				  if (l > n || l1 <= 0 || r1 > m) break;
    				  if (sum[l][r1] - sum[l][l1 - 1] != 2 * k - 1) break;
    				  ++ans;
    			}
    		}
    	}
    	printf("%lld
    ", ans);
    }
    signed main() {
    	int T = 1;
    	scanf("%d", &T);
    	// cin >> T;
    	while (T--) {
    		solve();
    	}
     
    }
    

    从下往上dp

    如果当前point(i,j)是一个满足条件的图形,当且仅当(str[i + 1][j - 1],str[i + 1][j], str[i+1][j+1] = '*')那么我们从下往上dp整个过程,注意取(min)

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 2e5 + 100;
    typedef long long LL;
    //#define int long long 
     
    char str[505][505];
    int dp[505][505];
    int n, m;
    
    
    void solve() {
    	scanf("%d%d", &n, &m);
    	memset(dp, 0, sizeof(dp));
    	for (int i = 1; i <= n; ++i) {
    		getchar();
    		for (int j = 1; j <= m; ++j) {
    			scanf("%c", &str[i][j]);
    			if (str[i][j] == '*') {
    				dp[i][j] = 1;
    			}
    		}
    	}
    	LL ans = 0;
    	for (int i = n; i  >= 1; --i) {
    		for (int j = 1; j <= m; ++j) {
    			if(str[i][j] == '*') {
    				dp[i][j] = min({dp[i + 1][j - 1], dp[i + 1][j], dp[i + 1][ j + 1]}) + 1;
    				ans += dp[i][j];
    			}
    		}
    	}
    	printf("%lld
    ", ans);
    
    }
    signed main() {
    
    	int T = 1;
    	scanf("%d", &T);
    	// cin >> T;
    	while (T--) {
    		solve();
    	}
     
    }
    
  • 相关阅读:
    gcc 编译器常用的命令行参数一览
    linux下源代码分析和阅读工具比较
    Linux系统——C/C++开发工具及环境搭建
    GDB调试——经验总结
    gdb调试的艺术——Debug技巧
    命令__cp、scp(Secure Copy)
    常用shell脚本命令
    命令__查找、替换、删除
    UltraEdit 删除空行
    命令__shell数字-字符串比较
  • 原文地址:https://www.cnblogs.com/waryan/p/14295332.html
Copyright © 2020-2023  润新知