P1101 单词方阵 (经典的八个方向上的搜索) -深度优先搜索关卡

21 篇文章 0 订阅

P1101 单词方阵

  • 题目提供者
  • 评测方式云端评测
  • 标签
  • 难度普及-
  • 时空限制1000ms / 128MB

 

题目描述

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

输入:
    8                     输出:
    qyizhong              *yizhong
    gydthkjy              gy******
    nwidghji              n*i*****
    orbzsfgz              o**z****
    hhgrhwth              h***h***
    zzzzzozo              z****o**
    iwdfrgng              i*****n*
    yyyygggg              y******g

输入输出格式

输入格式:

 

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

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

 

输出格式:

 

突出显示单词的n \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******
n*i*****
o**z****
h***h***
z****o**
i*****n*
y******g

 

思路:

经典题目啊,得把这道题写熟

 

#include<bits/stdc++.h>
using namespace std;
const int N=110;
char s[N][N];  //存储map
char a[]="yizhong";   //存储标准字符串 
bool vis[N][N];		 //存储访问标志 
int dx[8] = {0, 0, 1, -1, 1, 1, -1, -1}, //方向数组
    dy[8] = {1, -1, 0, 0, 1, -1, 1, -1};
int n;    
struct node 
{
	int x;     //结点用于存储路径,便于之后的输出 
	int y;	
}ss[N]; 


void dfs(int x,int y,int dir,int i) //x, y为当前坐标,dir是搜索方向,
{				//i是搜索到目标字符串的第几个字符(下标) ,从第二个字符 ‘i’开始 
	if(i==7)
	{
		ss[i].x=x;   //将最后一个字符所在的位置存入路径 
		ss[i].y=y;
            for(int j = 1; j <= 7; j++)
            {
            	vis[ss[j].x][ss[j].y]=1;       //将符合的字符都打上标记 
	    }
		return ;
	} 
		
	if(dir==-1)     //如果是第一次搜索
	{
		for(int j=0;j<8;j++)  //沿着8个方向搜索
		{
			int xx=x+dx[j];
			int yy=y+dy[j];
			if(s[xx][yy]==a[i])  //符合下一个字符时 
			{
				ss[i].x=x;   //记录当前路径 
				ss[i].y=y;
				dfs(xx,yy,j,i+1); //保持该方向继续搜索 
			}
			     //注意整个dfs不需要回溯,因为一直往一个方向就好了 		
		}
		return ;
	}
	
	int xx=x+dx[dir];   //保持方向也就是dx[dir]不变 
	int yy=y+dy[dir];
	if(s[xx][yy]==a[i])
	{
		ss[i].x=x;
		ss[i].y=y;
	    dfs(xx,yy,dir,i+1);	 
	}
	
}

int main()
{
	memset(s,'*',sizeof(s));  //初始化map 这样做的好处是 搜索时不必判断越界 
	memset(vis,0,sizeof(vis));
	cin>>n;
	for(int i=1;i<=n;i++)  //知识点!~~ 
		  cin>>s[i]+1;    //使得输入从s[1][1]开始 
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(s[i][j]=='y') //找到y字符就开始搜索 
			{
				dfs(i,j,-1,1);	 //方向初始为-1 
			}	
		}	
	}	
	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;
		
}

 

注意:

ss的下标是i  不是x 和y

  ss[i].x=x;   //记录当前路径 
  ss[i].y=y;

每次 ss[] 记录的是当前已经找到的字符的路径

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值