Codeforces Round #689 (Div. 2, based on Zed Code Competition)/1461B Find the Spruce
阿新 • • 發佈:2020-12-17
題目連結:https://codeforces.com/contest/1461/problem/B
題目大意:給定一個矩陣,求其中樓梯狀等腰三角形(叫它等腰樓梯吧0v0)的個數
題目思路:觀察下圖,發現最高點如果能構成更高階的等腰樓梯,那麼它的(i+1,j+1)(i+1,j)(i+1,j-1)三點必是低一級的等腰樓梯,順著這樣的想法,從下往上dp,得出狀態轉移方程dp[i][j] = min(dp[i + 1][j - 1], min(dp[i + 1][j], dp[i + 1][j + 1])) + 1
AC程式碼:
#include <iostream> #include <cstdio> #include <algorithm> #include <vector> #include <map> #include <string> #include <cstring> #include <set> #include <stack> #include <deque> #include <queue> using namespace std; typedef pair<int, int> PII; typedef long long ll; typedef unsigned long long ull; const int INF = 0x3f3f3f3f; const int N = 610, M = 3 * N; const int base = 1e9; const int P = 131; int n, m, t, k; char g[N][N]; int dp[N][N]; int main() { scanf("%d", &t); while (t--) { memset(dp, 0, sizeof(dp)); scanf("%d%d", &n, &m); for (int i = 1; i <= n; ++i) scanf("%s", g[i] + 1); for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) if (g[i][j] == '*') dp[i][j] = 1; int ans = 0; for (int i = n; i >= 1; --i) for (int j = 1; j <= m; ++j) if (dp[i][j]) { dp[i][j] = min(dp[i + 1][j - 1], min(dp[i + 1][j], dp[i + 1][j + 1])) + 1; ans += dp[i][j]; } printf("%d\n", ans); } return 0; }