洛谷 P1101 单词方阵(dfs)

题目链接:https://www.luogu.org/problemnew/show/P1101
DFS
题目描述:给一nXn的字母方阵,内可能蕴含多个“yizhong”单词。单词在方阵中是沿着同一方向连续摆放的。摆放可沿着8个方向的任一方向,同一单词摆放时不再改变方向,单词与单词之间[color=red]可以[/color]交叉,因此有可能共用字母。输出时,将不是单词的字母用“*”代替,以突出显示单词。例如:

输入:
    8                     输出:
    qyizhong              *yizhong
    gydthkjy              gy******
    nwidghji              n*i*****
    orbzsfgz              o**z****
    hhgrhwth              h***h***
    zzzzzozo              z****o**
    iwdfrgng              i*****n*
    yyyygggg              y******g

输入输出格式
输入格式
第一行输入一个数n。(7<=n<=100)。

第二行开始输入nXn的字母矩阵。

输出格式
突出显示单词的nXn矩阵。
输入输出样例
输入样例#1:

7
aaaaaaa
aaaaaaa
aaaaaaa
aaaaaaa
aaaaaaa
aaaaaaa
aaaaaaa

输出样例#1:

*******
*******
*******
*******
*******
*******
*******

此题显然是搜索,而且自带方向,我们只需从他所要求的单词的第一个字母开始。先找到‘y’,从‘y’向周围8个方向搜索,如果某个方向满足条件,就依这个方向往下搜索,直到把所有的字母找完。
AC代码如下:

#include 
#include 
#include 
#include 
using namespace std;
int n;
bool b[105][105];//标记
char a[101][101]={'0'};//存放原方阵
string str("yizhong");//存放指定字符串
int fx[8]={0,1,1, 1,0 ,-1,-1,-1},
    fy[8]={1,1,0,-1,-1,-1, 0, 1};//控制方向
void dfs(int i,int j,int k,int t)//k表示方向,t是已经找到的长度
{
    if(k==-1)//初始方向设为-1
    {
        for(int u=0;u<8;u++)
        {
            int x=i+fx[u];//试方向
            int y=j+fy[u];
            if(a[x][y]==str[t])//某个方向可行
                dfs(x,y,u,t+1);//就再从这个方向dfs
        }
        return;
    }
    if(t==7)//如果找完了
    {
        int dx=i,dy=j;//从最后那个字母开始
        for(int p=1;p<=7;p++)
        {
            b[dx][dy]=1;//依次往前标记为1
            dx=dx-fx[k];
            dy=dy-fy[k];
        }
        return;//返回
    }
    int x=i+fx[k];//k为找到的方向
    int y=j+fy[k];
    if(a[x][y]==str[t])
        dfs(x,y,k,t+1);//如果满足条件,就dfs
}
int main(){
    int i,j;
    scanf("%d",&n);
    for(i=1;i<=n;i++){      //读入单词方阵,也可以一行一行的读
        for(j=1;j<=n;j++){
            cin>>a[i][j];
        }
    }
    memset(b,0,sizeof(b));//清0标记,1代表满足条件
    for(i=1;i<=n;i++){
        for(j=1;j<=n;j++){
            if(a[i][j]=='y'){//找到一个y,开始dfs
                dfs(i,j,-1,1);
            }
        }
    }
    for(i=1;i<=n;i++){
        for(j=1;j<=n;j++){
            if(b[i][j])//标记为1的就输出,反之为*
                printf("%c",a[i][j]);
            else
                printf("*");
        }
        printf("\n");
    }
    printf("\n");
return 0;
}

总结,做dfs的题首要的是搜索逻辑(即按照怎样的原则,这往往在题目中有所体现)。

你可能感兴趣的:(DFS)