5165. CCC单词搜索

题目链接:https://www.acwing.com/problem/content/5168/

题目:

给定一个 R×C 的大写字母矩阵。

请你在其中寻找目标单词 W。

已知,目标单词 W 由若干个不同的大写字母构成。

目标单词可以遵循以下两种规则,出现在矩阵的水平、垂直或斜 45度线段中:

  • 单词出现在一条线段上。
  • 单词出现在两条相互垂直且存在公共端点的线段上。也就是说,单词首先出现在某线段上,直到某个字母后,转向 90 度,其余部分出现在另一条线段上。

具体可以参照图例。

请你计算,目标单词在给定矩阵中一共出现了多少次。

输入格式

第一行包含一个由若干个不同的大写字母构成的字符串,表示单词 W。

第二行包含整数 R。

第三行包含整数 C。

接下来 R行,每行包含 C 个大写字母,表示给定字母矩阵。

输出格式

一个整数,表示目标单词在给定矩阵中的出现次数。

数据范围

2≤|W|≤6
1≤R,C≤100

输入样例1:

MENU
5
7
F T R U B L K
P M N A X C U
A E R C N E O
M N E U A R M
M U N E M N S

输出样例1:

3

5165. CCC单词搜索_第1张图片

输入样例2:

NATURE
6
9
N A T S F E G Q N
S A I B M R H F A
C F T J C U C L T
K B H U P T A N U
D P R R R J D I R
I E E K M E G B E

输出样例2:

4

思路:dfs深搜,分两部分搜索,与以往不同的是,该题只能转一次弯,需要加参数判断,比较有意思

AC代码:

#include
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define endl "\n"
int n,m,k,sum,l;
int d1[4][2]={0,1,0,-1,1,0,-1,0};
int d2[4][2]={-1,-1,1,1,1,-1,-1,1};
char x[105][105];
string st;
void dfs1(int x1,int y1,int t,int ans)
{
	if(k==l&&ans<2)
	{
	sum++;
	return ;
	}
	for(int i=0;i<4;i++)
	{
		int xx=x1+d1[i][0];
		int yy=y1+d1[i][1];
		if(xx>n||yy>m||xx<1||yy<1)
		continue;
		if(x[xx][yy]==st[k])
		{
			k++;
			if(t!=i&&k!=2)
			dfs1(xx,yy,i,ans+1);
			else
			dfs1(xx,yy,i,ans);
			k--;
		}
	}
}
void dfs2(int x2,int y2,int t,int ans)
{
	if(k==l&&ans<2)
	{
	sum++;
	return ;
	}
	for(int i=0;i<4;i++)
	{
		int xx=x2+d2[i][0];
		int yy=y2+d2[i][1];
		if(xx>n||yy>m||xx<1||yy<1)
		continue;
		if(x[xx][yy]==st[k])
		{
			k++;
			if(t!=i&&k!=2)
			dfs2(xx,yy,i,ans+1);
			else
			dfs2(xx,yy,i,ans);
			k--;
		}
	}
}
void solve()
{
	cin>>st;
	l=st.size();
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cin>>x[i][j];
		}
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			if(x[i][j]==st[0])
			{
				k=1;
				dfs1(i,j,0,0);
				k=1;
				dfs2(i,j,0,0);
			}
		}
	}
	cout<>t;
	while(t--)
	solve();
	return 0;
}

5165. CCC单词搜索_第2张图片

你可能感兴趣的:(c++,c++,算法)