题目描述
给一n×nn \times nn×n的字母方阵,内可能蕴含多个“yizhong”单词。单词在方阵中是沿着同一方向连续摆放的。摆放可沿着 888 个方向的任一方向,同一单词摆放时不再改变方向,单词与单词之间可以交叉,因此有可能共用字母。输出时,将不是单词的字母用*代替,以突出显示单词。例如:
输入:
8 输出:
qyizhong yizhong
gydthkjy gy*****
nwidghji ni*****
orbzsfgz oz***
hhgrhwth hh***
zzzzzozo zo**
iwdfrgng i*****n
yyyygggg y****g
输入格式
第一行输入一个数nnn。(7≤n≤1007 \le n \le 1007≤n≤100)。
第二行开始输入n×nn \times nn×n的字母矩阵。
输出格式
突出显示单词的n×nn \times nn×n矩阵。
输入输出样例
输入 #1
7
aaaaaaa
aaaaaaa
aaaaaaa
aaaaaaa
aaaaaaa
aaaaaaa
aaaaaaa
输出 #1
输入 #2
8
qyizhong
gydthkjy
nwidghji
orbzsfgz
hhgrhwth
zzzzzozo
iwdfrgng
yyyygggg
输出 #2
yizhong
gy*****
ni*****
oz***
hh***
zo**
i*****n
y****g
思路:先把无关字母变为星号,减少后面搜索时间,从不是星号的字母开始深度优先搜索八个方向,搜索的时候记录所在行列下标,将符合条件的标记为1.然后最后把标记为0的并且不是星号的字符变为星号即可。
#include <bits/stdc++.h>
using namespace std;
char a[101][101];//方阵
int book[101][101];//标记数组
char s[7]={'y','i','z','h','o','n','g'};
int n;
vector <int> h,l;//存储记录走过的行列
void dfs(int step,int x,int y,int index,int b)//第几步 当前行 当前列 与index下标对比 b表示方向
{
if(x<1||y<1||x>n||y>n||a[x][y]=='*') return ;//判断越界和剪枝情况
if(a[x][y]!=s[index]) return;//如果和下标index不想等 剪枝返回
if(step==6)//如果判断是一种情况走完
{ h.push_back(x);
l.push_back(y);
for(int i=0;i<7;i++)
{ book[h[i]][l[i]]=1;//标记走过的行列号为1
}
l.pop_back();//回溯
h.pop_back();
return;
}
if(b==1)//右方向搜索
{ h.push_back(x);//记录当前走的行和列
l.push_back(y);
dfs(step+1,x,y+1,index+1,b);
l.pop_back();//回溯
h.pop_back();
}
if(b==2)//下
{ h.push_back(x);
l.push_back(y);
dfs(step+1,x+1,y,index+1,b);
l.pop_back();
h.pop_back();
}
if(b==3)//左
{ h.push_back(x);
l.push_back(y);
dfs(step+1,x,y-1,index+1,b);
l.pop_back();
h.pop_back();
}
if(b==4)//上
{ h.push_back(x);
l.push_back(y);
dfs(step+1,x-1,y,index+1,b);
l.pop_back();
h.pop_back();
}
if(b==5)//右上
{ h.push_back(x);
l.push_back(y);
dfs(step+1,x-1,y+1,index+1,b);
l.pop_back();
h.pop_back();
}
if(b==6)//右下
{ h.push_back(x);
l.push_back(y);
dfs(step+1,x+1,y+1,index+1,b);
l.pop_back();
h.pop_back();}
if(b==7)//左下
{ h.push_back(x);
l.push_back(y);
dfs(step+1,x+1,y-1,index+1,b);
l.pop_back();
h.pop_back();}
if(b==8)//左上
{ h.push_back(x);
l.push_back(y);
dfs(step+1,x-1,y-1,index+1,b);
l.pop_back();
h.pop_back();}
}
int main()
{
int i,j;
cin>>n;
for(i=1;i<=n;i++)//先把无关字母变为* 节省之后搜索时间
for(j=1;j<=n;j++)
{ cin>>a[i][j];
if(a[i][j]=='y'||a[i][j]=='i'||a[i][j]=='z'||a[i][j]=='h'||a[i][j]=='o'||a[i][j]=='n'||a[i][j]=='g')
continue;
a[i][j]='*';
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{ if(a[i][j]!='*'&&book[i][j]==0)//如果当前位置不是*并且没标记 向八个方向搜索
{ dfs(0,i,j,0,1);
dfs(0,i,j,0,2);
dfs(0,i,j,0,3);
dfs(0,i,j,0,4);
dfs(0,i,j,0,5);
dfs(0,i,j,0,6);
dfs(0,i,j,0,7);
dfs(0,i,j,0,8);
}
}
for(i=1;i<=n;i++)//标记为0的并且不是*的让它为*
for(j=1;j<=n;j++)
{ if(a[i][j]!='*'&&book[i][j]==0)
a[i][j]='*';
}
for(i=1;i<=n;i++)//输出
{ for(j=1;j<=n;j++)
cout<<a[i][j];
cout<<endl;
}
return 0;
}