LETTERS(DFS)

【题目描述】

给出一个row×colrow×col的大写字母矩阵,一开始的位置为左上角,你可以向上下左右四个方向移动,并且不能移向曾经经过的字母。问最多可以经过几个字母。

【输入】

第一行,输入字母矩阵行数RR和列数SS,1≤R,S≤201≤R,S≤20。

接着输出RR行SS列字母矩阵。

【输出】

最多能走过的不同字母的个数。

【输入样例】

复制代码
3 6
HFDFFB
AJHGDH
DGAGEH

【输出样例】

复制代码
6

原题链接:信息学奥赛一本通(C++版)在线评测系统

学习链接:《信息学奥赛一本通》搜索与回溯算法:1212LETTERS_哔哩哔哩_bilibili

【解题思路】

  1. 输入字母矩阵
  2. 从左上角作为第一步,开始对其上下左右四个方向开始搜索,若四个方向都已无法搜素或搜索完毕,则回溯
  3. 直到所有路径全部搜索完毕,找到最长的路径(不能出现相同字母)

代码如下:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int r,s;
char ch[25][25];//输入的字母矩阵 
int t[200];//桶,装入已访问的字母 
int x[4]={-1,1,0,0};//x方向的偏移量
int y[4]={0,0,-1,1};//y方向的偏移量
int maxx=0;//记录最长路径

void dfs(int nx,int ny,int len)
{
	maxx=max(maxx,len);//每到一个字母都比较一下路径 
	for(int i=0;i<4;i++)
	{
		//下一个出发搜索的字母坐标 
		int x1=nx+x[i];
		int y1=ny+y[i];
		
		//超出边界,跳过 
		if(x1<0 || x1>=r || y1<0 || y1>=s)
			continue;
		 
		//如果该位置的字母未装入过进桶t[],则可从该位置出发搜索 
		if(t[ch[x1][y1]-'A']==0)
		{
			t[ch[x1][y1]-'A']=1;//将该位置的字母装入桶里
			
			//步数要+1
			len++;
			
			//从该点出发继续向其四个符合条件的方向搜索
			dfs(x1,y1,len);
			
			//从该点出发的四个方向能到达的路径都已搜索完毕,回溯回来,并将搜索留下的痕迹清理干净
			//首先是路径要缩短回来
			len--;
			//再将该方向得的字母移出桶外,因为其他路径的搜索可能也会经过该字母
			t[ch[x1][y1]-'A']=0;
			
			//将继续从其他方向的字母出发搜索,即for的i++ 
			 
		} 
	}
}
 
int main()
{
	cin>>r>>s;
	for(int i=0;i<r;i++)
		for(int j=0;j<s;j++)
			cin>>ch[i][j]; 
	t[ch[0][0]-'A'] =1;  //注意要先将起点装入桶,避免它其他方向的字母跟他一样 
	dfs(0,0,1);//dfs(x,y,len);从(1,1)出发,步数len为1
	cout<<maxx<<endl;	
	return 0;
}

希望能帮助到各位同志,祝天天开心,学业进步!

相关推荐
qiuyunoqy6 分钟前
蓝桥杯算法之搜索章 - 2
算法·蓝桥杯·深度优先
初九之潜龙勿用11 分钟前
技术与情感交织的一生 (十一)
服务器·笔记·microsoft·印象笔记
2301_7639947112 分钟前
c++11特性
数据结构·c++·算法
极客BIM工作室14 分钟前
C++返回值优化(RVO):高效返回对象的艺术
java·开发语言·c++
序属秋秋秋23 分钟前
《C++初阶之STL》【模板参数 + 模板特化 + 分离编译】
开发语言·c++·笔记·学习·stl
Xueqian E31 分钟前
关于内核启动的optee: probe of firmware: optee failed with error -22 固件拉起失败的问题
笔记
澎恰恰oh33 分钟前
C++网络编程之Reactor实现
c++
快去睡觉~43 分钟前
力扣148:排序链表
算法·leetcode·链表
玄昌盛不会编程1 小时前
LeetCode——2683. 相邻值的按位异或
java·算法·leetcode
浮生卍流年1 小时前
C++模板知识点3『std::initializer_list初始化时逗号表达式的执行顺序』
开发语言·c++·qt