Codeforces Round #689 (Div. 2, based on Zed Code Competition)-B. Find the Spruce(DFS+記憶化搜尋)
阿新 • • 發佈:2020-12-13
題目連結
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 “.”.
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 “*”.
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…