letters
時間限制: 1 Sec 內存限制: 128 MB
題目描述
給出一個roe*coll的大寫字母矩陣,一開始的位置爲左上角,你可以向上下左右四個方向移動,並且不能移向曾經經過的字母。問最多可以經過幾個字母。
輸入
第一行,輸入字母矩陣行數R和列數S,1<=R,S<=20。
接着輸入R行S列的字母矩陣。
輸出
最多能走過的不同字母的個數。
樣例輸入
3 6
HFDFFB
AJHGDH
DGAGEH
樣例輸出
6
解法:DFS
-
要說這道題還是有些難度的,我來來回回試了好多遍才A
-
首先如何判斷當前走的位置是否是第一次遇到,如果是答案再加1,我們只需要開一個數組記錄就好了,我一直用bool
-
然後回溯要徹底,回溯時我們要把記錄是否走過的數組歸0,記錄次數的減1,如果爲0了,我們要把答案減掉1
AC代碼
#include<cstdio>
#include<iostream>
#define re register int
using namespace std;
int r,s,ans,d[222];
bool v[22][22]; char m[22][22];
const int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
inline void dfs(int x,int y,int tot) {
if(!d[m[x][y]]) tot++;//統計時要確保是第一次遇到
if(tot>ans) ans=tot;//統計答案
v[x][y]=1,d[m[x][y]]++;
for(re i=0;i<4;i++) {
int nx=x+dx[i],ny=y+dy[i];
if(nx<0||nx>s||ny<0||ny>r) continue;//注意邊界
if(v[nx][ny]) continue;
dfs(nx,ny,tot);
v[nx][ny]=0,d[m[nx][ny]]--;
if(!d[m[nx][ny]]) tot--;
}
}
int main() {
scanf("%d%d",&r,&s);
for(re i=1;i<=r;i++) {
for(re j=1;j<=s;j++) {
cin>>m[i][j];
}
}
dfs(1,1,0);
printf("%d",ans-1);//我也不知道爲啥要減1
return 0;
}