信息学奥赛一本通1212:LETTERS DFS

1212:LETTERS

时间限制: 1000 ms 内存限制: 65536 KB
提交数: 31678 通过数: 14328
【题目描述】
给出一个roe×col的大写字母矩阵,一开始的位置为左上角,你可以向上下左右四个方向移动,并且不能移向曾经经过的字母。问最多可以经过几个字母。

【输入】
第一行,输入字母矩阵行数R和列数S,1≤R,S≤20。

接着输出R行S列字母矩阵。

【输出】
最多能走过的不同字母的个数。

【输入样例】
3 6
HFDFFB
AJHGDH
DGAGEH
【输出样例】
6
思路:
这道题直接dfs,先搜索将走过的字母标记,遇到已经标记的跳过,不断回溯,搜索找到最大值
代码:

#include 
using namespace std;
char a[21][21];
int n,m;
int dx[4]={1,-1,0,0};//上下 
int dy[4]={0,0,1,-1};//移动方向 左右 
bool v[27];//用走过的字母值-'A'转化成0-26;
int ans; 
void dfs(int x,int y,int dep){//当前位置x,y 走过的个数dep
	if (dep>ans){
		ans=dep;
	} 
	int bx,by;
	for (int i=0;i<4;i++){
			bx=x+dx[i],by=y+dy[i];//bx,by可以避免直接在x上变化先+1,再减一,效果抵消 
			if (bx>n||bx<=0||by<=0||by>m){
				continue;
			}
			if (v[a[bx][by]-'A']==0){
				v[a[bx][by]-'A']=1;//标记 
				dfs(bx,by,dep+1);
				v[a[bx][by]-'A']=0;//回溯 
			}	
	}
}
int main(){
	cin>>n>>m;
	for (int i=1;i<=n;i++){
		for (int j=1;j<=m;j++){
			cin>>a[i][j];
		}
	}
	v[a[1][1]-'A']=1;
	dfs(1,1,1);
	cout<<ans; 
}

你可能感兴趣的:(深度优先,算法,图论)