题解
题目难度:简单
知识点:DFS、字符串、
方法(一):
第一步:获取单词的首字符
第二步:在字符迷阵中找到该字符
第三步:字符迷阵中从该字符开始,从水平、垂直、右下角方向与单词字符逐一比较
【注1】:在逐一比较时要考虑字符迷阵的边界,即m、n,访问字符迷阵时数组越界问题。
【注2】:当我们在考虑三个方向是,只考虑水平向左、垂直向下、右下角方向,字符迷阵中计数单词时不会重复计数。
#include<iostream>
#include<vector>
#include<string>
#define Maxn 100
using namespace std;
string a[Maxn];
int main(){
int T;
cin>>T;
while(T){
int m,n;
cin>>m>>n;
for(int i=0;i<m;i++){
cin>>a[i];
}
string word;
cin>>word;
int count=0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(a[i][j]==word[0]){
//水平方向
int flat=1;
for(int k=0;k<word.length();k++){
if((j+k>=n)||(a[i][j+k]!=word[k])) {
flat=0;
break;
}
}
if(flat) count++;
//垂直方向
flat=1;
for(int k=0;k<word.length();k++){
if((i+k>=m)||a[i+k][j]!=word[k]){
flat=0;
break;
}
}
if(flat) count++;
//右下角方向
flat=1;
for(int k=0;k<word.length();k++){
if((i+k>=m)||(j+k>=n)||a[i+k][j+k]!=word[k]){
flat=0;
break;
}
}
if(flat) count++;
}
}
}
cout<<count<<endl;
T--;
}
return 0;
}方法(二)
由于这里只能走固定的三个方向,我们可以采用常规的dfs方法。
简单分析:
1.dfs()方法中传入字符迷阵s1,单词s2,其中i、j代表当前访问的字符迷阵下标,k代表当前访问的单词下标。dir传入0、1、2,分别代表从当前位置向水平、垂直、右下角方向访问。该方法判断了从初始输入的i,j位置开始,dir方向是否为所要单词。
2.为该单词的判断条件时,当前访问的单词下标已经是单词长度,计数sum变量值加一。如果没有达到单词长度,再与单词比较之前考虑,i、j是否已经越界,如果没有越界就判断s1[i][j]与s2[k]的值是否相等,不相等直接结束。
3.如果相等,那么我们k+1,表示下一次比较的字符所对应的单词下标。这个,判断最初传入的dir方向,若为0,表示前面与单词比较都是按水平方向,那这时j+1,继续下一次dfs()。其他两个方向同理。
4.该dfs方法为初始传入的i、j确定的开始位置下标、dir方向是否是该单词。所以在main函数中用三重循环即可判断所有情况。
#include<iostream>
#include<string>
#define Maxn 100
using namespace std;
string s1[Maxn];
int sum=0;
void dfs(string* a,string s,int i,int j,int k,int dir,int m,int n){
if(k==s.length()){
// cout<<i<<j<<endl;
sum++;
return ;
}
if(i==m||j==n||a[i][j]!=s[k]) return ;
k++;
if(dir==0) dfs(a,s,i,j+1,k,dir,m,n);
else if(dir==1) dfs(a,s,i+1,j,k,dir,m,n);
else dfs(a,s,i+1,j+1,k,dir,m,n);
}
int main(){
int T;
cin>>T;
while(T){
int m,n;
cin>>m>>n;
for(int i=0;i<m;i++){
cin>>s1[i];
}
string s2;
cin>>s2;
sum=0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
for(int dir=0;dir<3;dir++){
dfs(s1,s2,i,j,0,dir,m,n);
}
}
}
cout<<sum<<endl;
T--;
}
return 0;
}
京公网安备 11010502036488号