题目链接:https://www.acwing.com/problem/content/5168/
题目:
给定一个 R×C 的大写字母矩阵。
请你在其中寻找目标单词 W。
已知,目标单词 W 由若干个不同的大写字母构成。
目标单词可以遵循以下两种规则,出现在矩阵的水平、垂直或斜 45度线段中:
具体可以参照图例。
请你计算,目标单词在给定矩阵中一共出现了多少次。
第一行包含一个由若干个不同的大写字母构成的字符串,表示单词 W。
第二行包含整数 R。
第三行包含整数 C。
接下来 R行,每行包含 C 个大写字母,表示给定字母矩阵。
一个整数,表示目标单词在给定矩阵中的出现次数。
2≤|W|≤6
1≤R,C≤100
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
3
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
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;
}