P1101 单词方阵

这是一道来自洛谷的编程题,要求处理一个nXn的字母矩阵,找出并突出显示其中的单词"yizhong"。题目允许单词沿8个方向连续摆放,可以交叉,输出时非单词字母用'*'替换。题目描述包括输入输出格式,并给出了解题过程中遇到的错误示例,如边界判断问题。
摘要由CSDN通过智能技术生成

洛谷

题目描述

给一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:
*******
*******
*******
*******
*******
*******
*******

















写了整整一晚上,极其暴力,各种小错误。比如:既然用的是1~n,scanf是就应该到从数组的1开始,而不是0;还有判断边界为<1 和>n而不是<0和>=n

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int n;
char buf[105][105];
bool ok[105][105];
char *word = "yizhong";
void yi(int i,int j)
{
    for(int k=1;k<=6;k++)
      if((i-k<=0) || (buf[i-k][j]!=word[k]))return;
    for(int k=0;k<=6;k++)ok[i-k][j]=1;
}
void er(int i,int j)
{
    for(int k=1;k<=6;k++)
      if((i+k>n) || (buf[i+k][j]!=word[k]))return;
    for(int k=0;k<=6;k++)ok[i+k][j]=1;
}
void san(int i,int j)
{
    for(int k=1;k<=6;k++)
      if((j+k>n) || (buf[i][j+k]!=word[k]))return;
    for(int k=0;k<=6;k++)ok[i][j+k]=1;
}
void si(int i,int j)
{
    for(int k=1;k<=6;k++)
      if((j-k<=0) || (buf[i][j-k]!=word[k]))return;
    for(int k=0;k<=6;k++)ok[i][j-k]=1;
}
void wu(int i,int j)
{
    for(int k=1;k<=6;k++)
      if((i-k<=0) ||(j-k<=0) ||(buf[i-k][j-k]!=word[k]))return;
    for(int k=0;k<=6;k++)ok[i-k][j-k]=1;
}
void liu(int i,int j)
{
    for(int k=1;k<=6;k++)
      if((i+k>n) ||(j-k<=0) ||(buf[i+k][j-k]!=word[k]))return;
    for(int k=0;k<=6;k++)ok[i+k][j-k]=1;
}
void qi(int i,int j)
{
    for(int k=1;k<=6;k++)
      if((i-k<=0) ||(j+k>n) ||(buf[i-k][j+k]!=word[k]))return;
    for(int k=0;k<=6;k++)ok[i-k][j+k]=1;
}
void ba(int i,int j)
{
    for(int k=1;k<=6;k++)
      if((i+k>n) ||(j+k>n) ||(buf[i+k][j+k]!=word[k]))return;
    for(int k=0;k<=6;k++)ok[i+k][j+k]=1;
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)scanf("%s",buf[i]+1);
    
    for(int i=1;i<=n;i++)
      for(int j=1;j<=n;j++)
          if(buf[i][j]=='y')
          {
              yi(i,j);er(i,j);san(i,j);si(i,j);wu(i,j);liu(i,j);qi(i,j);ba(i,j);
        }
    
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
          if(ok[i][j])printf("%c",buf[i][j]);
          else printf("%c",'*');
        
        cout<<"\n";    
    }
    
    return 0;
} 
原来代码不必这么长。。。恍然大悟,,int dx[10]={0,-1,1,0,0,-1,-1,1,1},dy[10]={0,0,0,-1,1,-1,1,-1,1}
然后一个8重循环代替8个函数 xx=x+dx[i];yy=y+dy[i];


修改版

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int n;
bool ok;
char buf[105][105];
bool can[105][105];
char *word="yizhong";
int dx[]={1,0,-1,0,1,1,-1,-1};
int dy[]={0,1,0,-1,1,-1,1,-1};
void dfs(int i,int j)
{
    for(int k=0;k<8;k++)
    {
        ok=1;
        if((i+6*dx[k]>n)||(i+6*dx[k]<1)||(j+6*dy[k]>n)||(j+6*dy[k]<1))continue;
        
        for(int m=1;m<7;m++)
        {
            int x=i+m*dx[k],y=j+m*dy[k];
            if(buf[x][y]!=word[m]){ok=0;break;}
        }
        
        if(ok)
            for(int m=0;m<7;m++)    //注意m从0开始,很重要!!! ‘y’不能* 
            {
               int x=i+m*dx[k],y=j+m*dy[k];
               can[x][y]=1;
            }          
    }
}
int main()
{   freopen("gmon.in","r",stdin); 
    cin>>n;
    for(int i=1;i<=n;i++)scanf("%s",buf[i]+1);  
    
    for(int i=1;i<=n;i++)for(int j=1;j<=n;j++) if(buf[i][j]=='y')dfs(i,j);  
    
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
          if(can[i][j])printf("%c",buf[i][j]);
          else printf("%c",'*');
        cout<<"\n";
    }    
    
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值