//给一n×n的字母方阵,内可能蕴含多个单词。单词在方阵中是沿着同一方向或不同方向连续摆放的。
//摆放可沿着 8 个方向的任一方向,同一单词摆放时可再改变方向,单词与单词之间可以交叉,因此有可能共用
//字母。输出时,将不是单词的字母用*代替,以突出显示单词。例如:
//第一行为单词方阵的大小n,n不超过200,第二行为待匹配的单词,长度不超过20,第三行及以下为n x n的字母方阵
//要求输出一个带*的字母方阵
/*
输入:
8
yizh
qyizhong
gydthkjy
nwidghji
orbzsfgz
hhgrhwth
zzzzzozo
iwdfrgng
yyyygggg
输出:
*yizh***
*y**h**y
**i****i
***z***z
hh**h**h
zz******
i*******
yy******
*/
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
char arr[300][300];
int mask[300][300];
int dir[8][2]={{0,1},{1,1},{1,0},{1,-1},{-1,0},{-1,-1},{0,-1},{-1,1}};
typedef struct{
int s[100][2];
}Steps;
char cmp[100];
Steps step;
void dfs(int k,int i,int j)
{
if(i<0||j<0)
{//非法条件
return ;
}
step.s[k][0]=i;step.s[k][1]=j;
if(k==strlen(cmp))
{//终止条件,记录步骤
for(int m=0;m<strlen(cmp);m++)
{
mask[step.s[m][0]][step.s[m][1]]=1;
}
return;
}
if(cmp[k]==arr[i][j])//继续搜索条件
for(int m=0;m<8;m++)
{
dfs(k+1,i+dir[m][0],j+dir[m][1]);
}
return ;
}
int main()
{
int n;cin>>n;
scanf("%s",cmp);
memset(mask,0,sizeof(mask));
for(int i=0;i<n;i++)
{
scanf("%s",arr[i]);
}
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(arr[i][j]==cmp[0])
{
dfs(0,i,j);//当前位置搜索开始;
//cout<<endl;
}
}
//cout<<endl;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
if(mask[i][j])
printf("%c",arr[i][j]);
else cout<<"*";
cout<<endl;
}
return 0;
}