C++ P1101 单词方阵

题目描述

洛谷传送门

给一 n×n 的字母方阵,内可能蕴含多个 yizhong 单词。单词在方阵中是沿着同一方向连续摆放的。摆放可沿着 8 个方向的任一方向,同一单词摆放时不再改变方向,单词与单词之间可以交叉,因此有可能共用字母。输出时,将不是单词的字母用 * 代替,以突出显示单词。

解题思路

做完题看了一下,大多数人都是用的dfs,就突然想到了一种 离谱 创新思路

用一个vis数组,标记这个点是否被用过(是否在单词里出现过),这个数组还有一个作用,就是输出时如果vis=1,就输出原来位置上的字母,否则输出*

每次判断当前扫描的点vis是否==1,如果是,就跳过这次扫描,否则就,,左下,右下扫描7个点,看连起来是不是yizhong,当然也有可能是gnohziy(yizhong反过来)

刚才的地方还有一个小优化,如果这次扫描的点不是yizhong的任何一个字母,就可以跳过,不需要再计算了

到这里你可能有2个问题:

  1. 为什么是,,左下,右下
  2. 为什么还有gnohziy

答:

  1. 如果有,的话,就会的前面的点的,完全重叠,就没有了意义,左上,右上同理

  2. 样例2(见下)

8
qyizhong
gydthkjy
nwidghji
orbzsfgz
hhgrhwth
zzzzzozo
iwdfrgng
yyyygggg

输出为:

*yizhong
gy******
n*i*****
o**z****
h***h***
z****o**
i*****n*
y******g

注意到最左侧的字符串,如果按我们的逻辑,就会反过来,然后被判定成不行,但其实是可以的

贴代码

//下面的横和竖就是右和下
#include<bits/stdc++.h>
#define int long long
using namespace std;
bool vis[105][105];
string s[105];
string f = "yizhong";
string ff = "gnohziy";
int n;
void heng(int x, int y) {
    if (!(n - y + 1 >= 7)) return;
    string t = "";
    int cnt = 0;
    for (int i = y; cnt < 7; i++, cnt++) {
        t += s[x][i];
    }
    if (t == f || t == ff) {
        cnt = 0;
        for (int i = y; cnt < 7; i++, cnt++) {
            vis[x][i] = 1;
        }
    }
}
void shu(int x, int y) {
    if (!(n - x + 1 >= 7)) return;
    string t = "";
    int cnt = 0;
    for (int i = x; cnt < 7; i++, cnt++) {
        t += s[i][y];
    }
    if (t == f || t == ff) {
        cnt = 0;
        for (int i = x; cnt < 7; i++, cnt++) {
            vis[i][y] = 1;
        }
    }
}
void zuoxia(int x, int y) {
    if (!(x >= 7 && n - y + 1 >= 7)) return;
    string t = "";
    int cnt = 0;
    for (int i = x, j = y; cnt < 7; i--, j++, cnt++) {
        t += s[i][j];
    }
    if (t == f || t == ff) {
        cnt = 0;
        for (int i = x, j = y; cnt < 7; i--, j++, cnt++) {
            vis[i][j] = 1;
        }
    }
}
void youxia(int x, int y) {
    if (!(n - x + 1 >= 7 && n - y + 1 >= 7)) return;
    string t = "";
    int cnt = 0;
    for (int i = x, j = y; cnt < 7; i++, j++, cnt++) {
        t += s[i][j];
    }
    if (t == f || t == ff) {
        cnt = 0;
        for (int i = x, j = y; cnt < 7; i++, j++, cnt++) {
            vis[i][j] = 1;
        }
    }
}
signed main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> s[i];
        s[i] = " " + s[i];
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            if (find(f.begin(), f.end(), s[i][j]) == f.end()) {
                continue;
            }
            if (vis[i][j]) continue;
            heng(i, j);
            shu(i, j);
            zuoxia(i, j);
            youxia(i, j);
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            if (vis[i][j]) {
                cout << s[i][j];
            } else {
                cout << "*";
            }
        }
        cout << endl;
    }
    return 0;
}

AC记录

在这里

posted on 2025-02-14 21:22  可爱楷玩算法  阅读(64)  评论(0)    收藏  举报

导航