P1101 单词方阵

题目描述

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

输入:
8 输出:
qyizhong yizhong
gydthkjy gy
*****
nwidghji ni*****
orbzsfgz oz
***
hhgrhwth hh***
zzzzzozo z
o**
iwdfrgng i*****n

yyyygggg y
****g

输入格式

第一行输入一个数nnn。(7≤n≤1007 \le n \le 1007≤n≤100)。

第二行开始输入n×nn \times nn×n的字母矩阵。
输出格式

突出显示单词的n×nn \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
*****
ni*****
oz
***
hh***
z
o**
i*****n

y
****g
思路:先把无关字母变为星号,减少后面搜索时间,从不是星号的字母开始深度优先搜索八个方向,搜索的时候记录所在行列下标,将符合条件的标记为1.然后最后把标记为0的并且不是星号的字符变为星号即可。

#include <bits/stdc++.h>
using namespace std;
char a[101][101];//方阵 
int book[101][101];//标记数组 
char s[7]={'y','i','z','h','o','n','g'};
int n; 
vector <int> h,l;//存储记录走过的行列 
void dfs(int step,int x,int y,int index,int b)//第几步  当前行 当前列 与index下标对比  b表示方向 
{ 
  if(x<1||y<1||x>n||y>n||a[x][y]=='*') return ;//判断越界和剪枝情况 
  if(a[x][y]!=s[index]) return;//如果和下标index不想等 剪枝返回 
  if(step==6)//如果判断是一种情况走完 
   { h.push_back(x);
     l.push_back(y);
     for(int i=0;i<7;i++) 
     { book[h[i]][l[i]]=1;//标记走过的行列号为1 
     }
     l.pop_back();//回溯 
    h.pop_back();
     return;
   } 
  if(b==1)//右方向搜索 
  { h.push_back(x);//记录当前走的行和列 
    l.push_back(y);
    dfs(step+1,x,y+1,index+1,b);
    l.pop_back();//回溯 
    h.pop_back();
  }
  if(b==2)//下 
  { h.push_back(x);
    l.push_back(y);
    dfs(step+1,x+1,y,index+1,b);
    l.pop_back();
    h.pop_back();
  }
  if(b==3)//左 
  { h.push_back(x);
    l.push_back(y); 
    dfs(step+1,x,y-1,index+1,b);
    l.pop_back();
    h.pop_back();
  }

  if(b==4)//上 
  { h.push_back(x);
    l.push_back(y);
    dfs(step+1,x-1,y,index+1,b);
    l.pop_back();
    h.pop_back();
  }
  if(b==5)//右上 
  { h.push_back(x);
    l.push_back(y);
    dfs(step+1,x-1,y+1,index+1,b);
    l.pop_back();
    h.pop_back();
  }
  if(b==6)//右下 
  { h.push_back(x);
    l.push_back(y);
    dfs(step+1,x+1,y+1,index+1,b);
	l.pop_back();
    h.pop_back();}
  if(b==7)//左下 
  { h.push_back(x);
    l.push_back(y);
    dfs(step+1,x+1,y-1,index+1,b);
	l.pop_back();
    h.pop_back();}
  if(b==8)//左上 
  { h.push_back(x);
    l.push_back(y);
    dfs(step+1,x-1,y-1,index+1,b);
	l.pop_back();
    h.pop_back();}
}
 int main()
 {
 	int i,j;
 	cin>>n; 
	for(i=1;i<=n;i++)//先把无关字母变为* 节省之后搜索时间 
	 for(j=1;j<=n;j++)
	  { cin>>a[i][j];
	    if(a[i][j]=='y'||a[i][j]=='i'||a[i][j]=='z'||a[i][j]=='h'||a[i][j]=='o'||a[i][j]=='n'||a[i][j]=='g')
	      continue;
	     a[i][j]='*';
		}
	for(i=1;i<=n;i++)
	 for(j=1;j<=n;j++)
	 { if(a[i][j]!='*'&&book[i][j]==0)//如果当前位置不是*并且没标记  向八个方向搜索
	    { dfs(0,i,j,0,1);
	      dfs(0,i,j,0,2);
	      dfs(0,i,j,0,3);
	      dfs(0,i,j,0,4);
	      dfs(0,i,j,0,5);
	      dfs(0,i,j,0,6);
	      dfs(0,i,j,0,7);
	      dfs(0,i,j,0,8);
	    }
	 }
	 for(i=1;i<=n;i++)//标记为0的并且不是*的让它为* 
	  for(j=1;j<=n;j++)
	  { if(a[i][j]!='*'&&book[i][j]==0)
	     a[i][j]='*';
	  }
	for(i=1;i<=n;i++)//输出 
	 { for(j=1;j<=n;j++)
	   cout<<a[i][j];
	   cout<<endl;
	 }
	
	 return 0;
 }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乔梦圆的博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值