【题目描述】
给出一个roe×col的大写字母矩阵,一开始的位置为左上角,你可以向上下左右四个方向移动,并且不能移向曾经经过的字母。问最多可以经过几个字母。
【输入】
第一行,输入字母矩阵行数R和列数S,1≤R,S≤20。
接着输出R行S列字母矩阵。
【输出】
最多能走过的不同字母的个数。
【输入样例】
3 6 HFDFFB AJHGDH DGAGEH
【输出样例】
6
思路:
此题显然是搜索与回溯的典例,数据范围较小,可以用搜索这种较暴力的方法做出来。一点点独特的地方就是相同的字母
不能走,这显然需要一个新思路。所以我设置了一个数组,共26个,每一个数组0或1代表这个字母可不可以走,其他和
前面的马走日,迷宫等题大同小异
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
void dfs(int,int);
char a[22][22];//字符数组
bool b[30] = {};//判断字母是否能走,初始化为0
int dx[4] = {1,-1,0,0},dy[4] = {0,0,1,-1};//模拟四种走法
int ans,tot,m,n;
void dfs(int,int);
int main()
{
cin >> n >> m;
for(int i = 1;i <= n;i ++)
for(int j = 1;j <= m;j ++)
cin >> a[i][j];
dfs(1,1);//起点为1,是为了防止数组越界
cout << ans;
return 0;
}
void dfs(int x,int y)
{
if(b[a[x][y]-64] == 0)//比如说Z这个大写字母,ASCII值是90,在子母中位置为26,所以减去64
{
b[a[x][y]-64] = 1;//代表走过了
tot ++;//路径上多加一个
ans = max(ans,tot);//更新答案
}
int t = tot;//这里存一下数据,原因就是:比如说,在这个字母后面有三条路可以走,现在的路径上已经有了三个字母。那么,当走完一条路回溯时,可以直接用这个点的数据。简便而且记录了tot的值
for(int k = 0;k < 4;k ++)
{
tot=t;
if(x+dx[k] >= 1&&x+dx[k] <= n&&y+dy[k] >= 1&&y+dy[k] <= m&&b[a[x+dx[k]][y+dy[k]]-64] == 0) //熟悉的边界条件以及能不能走
{
dfs(x+dx[k],y+dy[k]);//递归搜索
b[a[x+dx[k]][y+dy[k]]-64] = 0;//回溯,将用过的点变为0
}
}
return;
}