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   可爱楷玩算法  阅读(4)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~
点击右上角即可分享
微信分享提示