CT-1 C 找单词 题解
其实是个原题(原题链接),就是把他的 yizhong 换成了自己输入,非常简单。
我们可以直接爆搜,每次标记当前在矩阵里的位置和当前是单词的第几个字符,如果搜到了单词尾就标记前面搜的,然后往 8 个方向继续搜。dfs 函数大概长这样:
void dfs(int x,int y,int t)//t是单词第几个字母
{
if(x<1||y<1||x>n||y>n)//判断越界
return;
if(a[x][y]!=s[t])//单词不符合
return;
if(t==l-1)//到单词尾了
{
f=1;
g[x][y]=1;
return;
}
for(int i=0;i<8;i++)
dfs(x+dx[i],y+dy[i],t+1);
if(f)//往回标
g[x][y]=1;
if(!t)//回到开头了就不标了
f=0;
}
但是这个代码有个问题,就是如果单词在里面是弯曲的,他也会标出来。比如这个样例:
jqqt
4
jqqa
aata
qqwe
rwer
正常应该输出全 *,但是这个代码输出:
jqq*
**t*
****
****
所以我们要加一个当前方向的参数,如果是单词第一个就搜 8 个方向,否则就往当前这个方向搜。改良后的函数长这样:
void dfs(int x,int y,int d,int t)//d是当前方向
{
if(x<1||y<1||x>n||y>n)
return;
if(a[x][y]!=s[t])
return;
if(t==l-1)
{
while(t--)//往前标
{
g[x][y]=1;
x-=dx[d],y-=dy[d];
}
g[x][y]=1;
return;
}
if(!t)//是单词头搜8方向
for(int i=0;i<8;i++)
dfs(x+dx[i],y+dy[i],i,t+1);
else//否则按这个方向继续走
dfs(x+dx[d],y+dy[d],d,t+1);
}
这样就能正常处理了。
完整 std:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int dx[]={1,0,-1,0,1,-1,1,-1},dy[]={0,1,0,-1,1,1,-1,-1};
int n;
char a[110][110],s[15];
int g[110][110],l;
void dfs(int x,int y,int d,int t)
{
if(x<1||y<1||x>n||y>n)
return;
if(a[x][y]!=s[t])
return;
if(t==l-1)
{
while(t--)
{
g[x][y]=1;
x-=dx[d],y-=dy[d];
}
g[x][y]=1;
return;
}
if(!t)
for(int i=0;i<8;i++)
dfs(x+dx[i],y+dy[i],i,t+1);
else
dfs(x+dx[d],y+dy[d],d,t+1);
}
int main()
{
scanf("%s",s);
l=strlen(s);
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>a[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(a[i][j]==s[0])//如果单词开头找到了就开始搜
dfs(i,j,0,0);
for(int i=1;i<=n;i++)//处理完了输出
{
for(int j=1;j<=n;j++)
if(g[i][j])
printf("%c",a[i][j]);
else
printf("*");
printf("\n");
}
return 0;
}

浙公网安备 33010602011771号