Codeforces Round #689 (Div. 2, based on Zed Code Competition)-B. Find the Spruce(DFS+記憶化搜尋)
題目連結
Codeforces Round #689 (Div. 2, based on Zed Code Competition)-B. Find the Spruce
Description
- Holidays are coming up really soon. Rick realized that it’s time to think about buying a traditional spruce tree. But Rick doesn’t want real trees to get hurt so he decided to find some in an n×m matrix consisting of “*” and “.”.
To find every spruce first let’s define what a spruce in the matrix is. A set of matrix cells is called a spruce of height k with origin at point (x,y) if:
All cells in the set contain an "".
For each 1≤i≤k all cells with the row number x+i−1 and columns in range [y−i+1,y+i−1] must be a part of the set. All other cells cannot belong to the set.
Input
- Each test contains one or more test cases. The first line contains the number of test cases t (1≤t≤10).
The first line of each test case contains two integers n and m (1≤n,m≤500) — matrix size.
Next n lines of each test case contain m characters ci,j — matrix contents. It is guaranteed that ci,j is either a “.” or an “*”.
It is guaranteed that the sum of n⋅m over all test cases does not exceed 500^2 (∑n⋅m≤500^2).
Output
- For each test case, print single integer — the total number of spruces in the matrix.
輸入
4
2 3
.*.
***
2 3
.*.
**.
4 5
.***.
*****
*****
*.*.*
5 7
..*.*..
.*****.
*******
.*****.
..*.*..
輸出
5
3
23
34
思路
- 思路:實際上可以把題目意思轉化為所有以"*"的點為樹的頂點所能構成的雲杉樹的深度的和,例如樣例一,第一排中間的"*“為頂點構成的樹的深度為2,而第二排中間的”*"為頂點構成的樹的深度為1所以ans=2+1+1+1=5
- 方法:對每一個“*”用 dfs搜尋 樹的深度,因為要保證樹完整所以dfs返回值為最小的樹的深度+1。
- 注意:要用記憶化搜尋(二維陣列dp儲存dfs的值,避免重複搜尋造成時間浪費),不然會超時。
AC程式碼
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
string s[600];
int dp[600][600];//儲存dfs的值
int sum=0,n,m;
int dfs(int x,int y){//dfs求樹的深度
if(dp[x][y]) return dp[x][y];//如果搜尋過就返回dp
int flag=0;//判斷是否能繼續往下
if(x+1<n&&y-1>=0&&x+1>=0&&y+1<m){
if((s[x+1][y]=='*')&&(s[x+1][y-1]=='*')&&(s[x+1][y+1]=='*')){
flag=1;
}
}
if(flag) return dp[x][y]=1+min(min(dfs(x+1,y),dfs(x+1,y-1)),dfs(x+1,y+1));//因為要保證樹完整所以要求最小的樹的深度
else return dp[x][y]=1;//深度為1即一個點
}
int main(){
int t;
cin>>t;
while(t--){
memset(dp,0,sizeof(dp));
cin>>n>>m;
sum=0;
for(int i=0;i<n;i++){
cin>>s[i];
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(s[i][j]=='*'){
sum+=dfs(i,j);
}
}
}
cout<<sum<<endl;
}
}
- 一開始沒用記憶化搜尋結果Time limit exceeded…
相關文章
- Codeforces Round #491 (Div. 2) B. Getting an A
- Codeforces Round 977 (Div. 2, based on COMPFEST 16 - Final Round)
- Codeforces Round #676 (Div. 2) B. Putting Bricks in the Wall
- Codeforces Round #844 (Div. 1 + Div. 2, based on VK Cup 2022 - Elimination Round) A-D
- Codeforces Round 928 (Div. 4) B. Vlad and Shapes
- Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) B. Batch SortIntelBAT
- 【CodeForces訓練記錄】Codeforces Round 982 (Div. 2)
- 【CodeForces訓練記錄】Codeforces Round 986 (Div. 2)
- Codeforces Round #537 (Div. 2)B. Average Superhero Gang Power (貪心+暴力)
- Codeforces Round #541 (Div. 2)
- Codeforces Round 940 (Div. 2)
- Codeforces Round 934 (Div. 2)
- Codeforces Round 932 (Div. 2)
- Codeforces Round 948 (Div. 2)
- Codeforces Round #639 (Div. 2)
- Codeforces Round #672 (Div. 2)
- Codeforces Round #682 (Div. 2)
- Codeforces Round #678 (Div. 2)
- Codeforces Round #673 (Div. 2)
- Codeforces Round 987 (Div. 2)
- Codeforces Round 976 (Div. 2)
- Codeforces Round 975 (Div. 2)
- Codeforces Round 986 (Div. 2)
- Codeforces Round 973 (Div. 2)
- Codeforces Round 969 (Div. 2)
- Codeforces Round 873 (Div. 2)
- Codeforces Round 967 (Div. 2)
- Codeforces Round 965 (Div. 2)
- Codeforces Round 963 (Div. 2)
- Codeforces Round 979 (Div. 2)
- Codeforces Round 972 (Div. 2)
- Codeforces Round 949 (Div. 2)
- Codeforces Round 955 (Div. 2)
- Codeforces Round 951 (Div. 2)
- Codeforces Round 961 (Div. 2)
- Codeforces Round 958 (Div. 2)
- Codeforces Round 960 (Div. 2)
- Codeforces Round 953 (Div. 2)