P1101 单词方阵

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

输入:
    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)。第二行开始输入n×n的字母矩阵。输出格式:突出显示单词的n×n矩阵。

乍眼一看,这题的第一个思路是深度优先搜索。然而苦于难度高,没有想到具体的实现过程。

我换了个思路:

我们可以对于每一个字符,沿着八个方向寻找,把依次找到的七个字符存入一个字符串里,只要判断它是不是“yizhong”就能确定了!然后,创建一个bool数组,存储需要保留的字符位置。对于判断是“yizhong”的搜索途径,把沿途的字符位置都打上true,然后解决问题!

额。。。我自己都没听懂。。。

以上述输入输出为例,先创建一个bool数组,初始化全为false。我们找到了第一排第二个字符,然后向八个方向搜索。发现往右边搜索(即横坐标不断加一)可以得到完整的yizhong。于是这几个字符在数组中体现为true,也就是bool数组的[0][1]~[0][7]都是true。全部搜索完以后,遍历bool数组,遇到false输出“*”,遇到true说明这是yizhong的有效组成成分,于是输出它在原来的字母矩阵中对应的字符。

程序还有优化的空间。其实不需要检测全部8个方向,可以只搜索上、右上、右、右下四个方向,如果它们对应的是yizhong,则搜索到了一个。对于其它四个方向,它们对应的应该是yizhong的反序,也就是gnohziy。

还是拿上面的例子。我们可以从第一行最后一个字符([0][7])向左搜索。此时搜索到的是yizhong的反序,也就是gnohziy!这和从从第一行第二个往右搜索搜到yizhong是等价的!

#include<bits/stdc++.h>
using namespace std;
#define UP 1
#define RIGHT_UP 2
#define RIGHT 3
#define DOWN_RIGHT 4
//四个方向
char a[101][101];//保存字符矩阵
char yizhong[8]="yizhong";
char yizhong_reverse[8]="gnohziy";
char cache[7];
bool needToSave[101][101];//保存输出星号还是原字符
int n;
bool ok()
{
    for(int i=0;i<7;i++)//是不是搜索到了
    {
        if(cache[i]!=yizhong[i]&&cache[i]!=yizhong_reverse[i]) return false;
        //正序反序都对不上,不是。
    }
    return true;
}
void clear()
{
    for(int i=0;i<7;i++)
    {
        cache[i]=‘ ‘;
    }
}
void search(int x,int y,int direction)
{
    switch(direction)
    {
        case UP:
            for(int i=0;i<7;i++)
            {
                if(y-i<0)//越界了,肯定不是
                {
                    clear();//已经搜索到的无效了
                    return;
                }
                cache[i]=a[x][y-i];
            }
            break;
        case RIGHT_UP:
            for(int i=0;i<7;i++)
            {
                if(x+i>n-1||y-i<0)
                {
                    clear();
                    return;
                }
                cache[i]=a[x+i][y-i];
            }
            break;
        case RIGHT:
            for(int i=0;i<7;i++)
            {
                if(x+i>n-1)
                {
                    clear();
                    return;
                }
                cache[i]=a[x+i][y];
            }
            break;
        case DOWN_RIGHT:
            for(int i=0;i<7;i++)
            {
                if(x+i>n-1||y+i>n-1)
                {
                    clear();
                    return;
                }
                cache[i]=a[x+i][y+i];
            }
            break;
    }
    if(ok())
    {
        switch(direction)
        {
        case UP:
            for(int i=0;i<7;i++)
            {
                needToSave[x][y-i]=true;
            }
            break;
        case RIGHT_UP:
            for(int i=0;i<7;i++)
            {
                needToSave[x+i][y-i]=true;
            }
            break;
        case RIGHT:
            for(int i=0;i<7;i++)
            {
                needToSave[x+i][y]=true;
            }
            break;
        case DOWN_RIGHT:
            for(int i=0;i<7;i++)
            {
                needToSave[x+i][y+i]=true;
            }
            break;
        }
    }
    clear();//供下一次使用
}
int main()
{
    memset(a,‘ ‘,sizeof(a));
    memset(cache,‘ ‘,sizeof(cache));
    memset(needToSave,false,sizeof(needToSave));
    scanf("%d",&n);
    getchar();
    getchar();
    for(int i=0;i<n;i++)
    {
        gets(a[i]);
    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            for(int k=1;k<=4;k++)
                search(i,j,k);
        }
    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            if(needToSave[i][j]==false) printf("*");
            else printf("%c",a[i][j]);
        }
        cout<<endl;
    }
}

原文地址:https://www.cnblogs.com/jiangyuechen/p/12305592.html

时间: 2024-10-15 19:45:10

P1101 单词方阵的相关文章

Luogu P1101 单词方阵

明明是一道水题,我还找不出 bug 来...原本在 DFS 途中记录单词串,只好使用笨方法,在结尾加一个 for 记录单词串.终于过了. 思路:枚举图中每一个点进行 DFS,途中判断访问的点是否为连续元素("yizhong"字符串中连续),如果不是返回:进行下一层 DFS,如果返回值 True 则直接层层返回 True,强行退出. 1 /* P1101 单词方阵 2 * Au: GG 3 */ 4 #include <cstdio> 5 #include <cstdl

P1101 单词方阵【洛谷】

//题目----------------------------------------------------------------------------------------- 传送门: http://www.luogu.org/problem/show?pid=1101 P1101 单词方阵 题目描述 给一nXn的字母方阵,内可能蕴含多个“yizhong”单词.单词在方阵中是沿着同一方向连续摆放的.摆放可沿着8个方向的任一方向,同一单词摆放时不再改变方向,单词与单词之间[color=

洛谷——P1101 单词方阵

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

洛谷P1101 单词方阵——S.B.S.

题目描述 给一nXn的字母方阵,内可能蕴含多个“yizhong”单词.单词在方阵中是沿着同一方向连续摆放的.摆放可沿着8个方向的任一方向,同一单词摆放时不再改变方向,单词与单词之间[color=red]可以[/color]交叉,因此有可能共用字母.输出时,将不是单词的字母用“*”代替,以突出显示单词.例如: 输入: 8 输出: qyizhong *yizhong gydthkjy gy****** nwidghji n*i***** orbzsfgz o**z**** hhgrhwth h***

P1101 单词方阵 简单dfs

题目描述 给一n \times nn×n的字母方阵,内可能蕴含多个“yizhong”单词.单词在方阵中是沿着同一方向连续摆放的.摆放可沿着 88 个方向的任一方向,同一单词摆放时不再改变方向,单词与单词之间可以交叉,因此有可能共用字母.输出时,将不是单词的字母用*代替,以突出显示单词.例如: 输入: 8 输出: qyizhong *yizhong gydthkjy gy****** nwidghji n*i***** orbzsfgz o**z**** hhgrhwth h***h*** zzz

洛谷 P1101 单词方阵

不算搜索的搜索 思路和很多人的一样,因为只要找到两个字母,方向就确定了,记录下方向,剩下的暴力即可. #include<iostream> #include<cstdio> #include<algorithm> using namespace std; int n; int fx[9][2]={{0,0},{1,0},{-1,0},{0,1},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1}};//存方向,循环起来比较方便 char map[101

落谷P1101 单词方阵 //参考代码

1 #include<iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 const int N = 105; 6 char s[N][N], a[] = "yizhong"; 7 bool vis[N][N]; 8 int n; 9 int dx[8] = {0, 0, 1, -1, 1, 1, -1, -1}, 10 dy[8] = {1, -1,

落谷P1101 单词方阵 //未完成

1 #include<iostream>/*cout<<endl; 2 for(int i=1;i<=n;i++) 3 for(int j=0;j<n;j++){ 4 5 cout<<a[i][j]; 6 if(j==n-1)cout<<endl; 7 }*/ 8 #include<cstring> 9 #include<cstdio> 10 using namespace std; 11 const int wd=101

洛谷 P1101 【单词方阵】题解

来先写一下思路: 1.一一枚举开始的位置 2.朝8个方向搜索(其实不如说是递归) 3.在搜索到后标记搜索到了 4.通过标记在搜索完成后再标记哪些地方是"yizhong" 5.输出 严格来说,此题不算是深搜,到不如说是递归,因为只需要往前探路,不需要回溯,下面是代码: #include<iostream>#include<cstdio>using namespace std;int pd,wx[9] = {0,-1,-1,0,1,1,1,0,-1},wy[9] =