P1101 單詞方陣【DFS】

Mercury_Lc發表於2020-10-02

https://www.luogu.com.cn/problem/P1101

題目描述

給一n \times nn×n的字母方陣,內可能蘊含多個“yizhong”單詞。單詞在方陣中是沿著同一方向連續擺放的。擺放可沿著 88 個方向的任一方向,同一單詞擺放時不再改變方向,單詞與單詞之間可以交叉,因此有可能共用字母。輸出時,將不是單詞的字母用*代替,以突出顯示單詞。例如:

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

輸入格式

第一行輸入一個數nn。(7 \le n \le 1007≤n≤100)。

第二行開始輸入n \times nn×n的字母矩陣。

輸出格式

突出顯示單詞的n \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******
n*i*****
o**z****
h***h***
z****o**
i*****n*
y******g

題解:判斷某一個點是否為"yizhong"的開始,即判斷是否為'y',這時候可以直接向八個方向進行DFS。也可以繼續判斷這八個方向中,下一個字元是'i'的是那個,那麼就按這個方向DFS。

在DFS時需要注意,當前遍歷的"yizhong"的路徑如何儲存,這裡通過一個path[ ] 來儲存,如果最後遍歷到 'g' ,即當我們的遍歷cnt==7時,那就將 path[ ] 裡面的座標標記成1,代表這些是符合要求的。

1、如果還未到7次,說明當前還需要繼續DFS,一種是當下一個字元與之相匹配時,這時,cnt+ 1,繼續按該方向遍歷。

2、當我們遍歷到cnt == 6 時,就已經遍歷完字串了,這時候需要我們儲存下來路徑,就是又進行了DFS,但是並沒有將下一個存到vis裡面。

3、也可以調整一下下面的程式碼順序,不再遞迴cnt==6這一次。

 

自己寫的很難看,看了題解之後重新寫了一遍。

#include <stdio.h>
#include <string.h>
#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
char s[200][200];
char parent[] = "yizhong";
int vis[200][200];
struct node {
    int x,y;
}path[10];
int dx[] = {1,1,1,0,0,-1,-1,-1};
int dy[] = {0,1,-1,1,-1,0,1,-1};
void dfs(int x,int y,int cnt, int k){
    if(cnt == 7){
        for(int i = 0; i < 7; i ++){
            vis[path[i].x][path[i].y] = 1;
        }
    }
    else {
        int tx = x + dx[k];
        int ty = y + dy[k];
        if(cnt == 6 || s[tx][ty] == parent[cnt+1]){
            path[cnt].x = x;
            path[cnt].y = y;
            dfs(tx,ty,cnt+1,k);
        }
    }
}
int main()
{
    int n;
    cin >> n;
    for(int i = 0; i < n; i ++)
    {
        cin >> s[i];
    }
    memset(vis,0,sizeof(vis));
    for(int i = 0; i < n; i ++){
        for(int j = 0; j < n; j ++)
        {
            if(s[i][j] == 'y'){
                for(int k = 0; k < 8; k ++){
                    int ti = i + dx[k];
                    int tj = j + dy[k];
                    if(s[ti][tj] == 'i'){
                        dfs(i,j,0,k);

                    }
                }
            }
        }
    }
    for(int i = 0; i < n; i ++)
    {
        for(int j = 0; j < n; j ++)
        {
            if(vis[i][j]) cout << s[i][j];
            else cout << '*' ;
        }
        cout << endl;
    }
    return 0;
}

 

相關文章