题目描述
给出一个roe×col的大写字母矩阵,一开始的位置为左上角,你可以向上下左右四个方向移动,并且不能移向曾经经过的字母。问最多可以经过几个字母。
输入
第一行,输入字母矩阵行数R和列数S,1≤R,S≤20。接着输出R行S列字母矩阵
输出
最多能走过的不同字母的个数。
输入样例
3 6
HFDFFB
AJHGDH
DGAGEH
输出样例
6
思路:需要一个方向数组记录走的方向,便于循环;地图数组,输入地图;vis数组和b数组记录是否用过格子/字母;Smax记录在total(走的步数)中最大值
变化:
这里dfs函数的参数变成了三个,即dfs(int x,int y,int step)
增加了dir方向数组
易错:
确认二维数组是否从0开始,或者从1开始,并且从一而终
确认字母是否被用过时,一定一定记得减去64或者‘A’
//letters问题
#include<iostream>
#include<math.h>
using namespace std;
char a[30][30];//地图,map函数已经被定义,不可命名为 map
int b[30],vis[30][30];//记录这个字母/格子是否被用过,只有0和1两个元素
int s[4][2] = { {1,0},{-1,0},{0,1},{0,-1} };//方向数组:下上右左,当然顺序无所谓,所以算符数目是4
//方向数组具体内部排列:每一行都是一次移动xy坐标的变化
//10
//-10
//01
//0-1
int m, n;//二维数组的行列
int smax;//Smax纪录最大步数
void dfs(int nx,int ny,int step)//自定义void和int函数仍然使用不熟练
{
smax = max(smax, step);
for (int i =0; i<4; i++) //四个移动方向循环
{
int x = nx +s[i][0];//移动
int y = ny +s[i][1];//移动
if (x <m && y <n && x >=0 && y >=0 && b[a[x][y] - 'A'] == 0 && vis[x][y] == 0)//简直了,就疯狂堆限制,仿佛奶茶疯狂放小料:不过边界,在地图内,没被用过
{
b[a[x][y]-'A'] = 1;
vis[x][y] = 1;
dfs(x, y, step + 1);
b[a[x][y]-'A'] =0;//回溯
vis[x][y] = 0;//又回到最初的起点,呆呆地站在镜子前
}
}
}
int main()
{
cin >> m>>n;
for (int i =0; i <m;i++)
{
for (int j =0; j <n; j++)//各种细节如<和<=,还有从0还是1开始容易出bug
cin >> a[i][j];
}
b[a[0][0]-'A'] = 1;
vis[0][0] = 1;
dfs(0,0,1);
cout <<smax;
}