【洛谷】P1101 单词方阵(深搜 or 暴力模拟)题解

原题链接:https://www.luogu.org/problem/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矩阵。

输入输出样例

输入样例#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

说明

时空限制:1000ms 125M

(连成的“龙”为atoucheatactactouchoose)

NOIp2000提高组第三题

思路:这道题可以用dfs来做,也可以直接暴力模拟。


第一种:搜索

遍历一遍方阵,先找到第一个单词字母“ y ”,然后遍历一遍方向,分别向八个方向搜索,如果下一个单词字母相应符合,则继续以此方向搜索,搜到完整单词时,将该单词字母的位置标记,输出时只需要输出有标记的,其他输出“ * ”即可。

代码如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std; 
int n; 
char ch[105][105];	//输入的字符 
char word[]="yizhong";
int px[105],py[105];	//记录横纵坐标 
bool vis[105][105];		//标记数组 
int xx[8]={0, 0, 1, 1, 1,-1,-1,-1};//搜索的方向,1表示向右,-1表示向左 
int yy[8]={1,-1,-1, 0, 1,-1, 1, 0};//搜索的方向,1表示向下,-1表示向上 
//深搜,a表示行位置,b表示列位置,c表示单词字母位置,d表示搜索方向下标 
int dfs(int a,int b,int c,int d) 
{
	px[c]=a;	//记录当前单词字母行位置 
	py[c]=b;	//记录当前单词字母列的位置 
	if(c==6)	//如果是最后一个单词字母 
	{
		for(int i=0;i<7;i++)	//遍历,标记单词字母的位置 
			vis[px[i]][py[i]]=true;
		return 0;
	} 
	//如果不越界、单词长度不超出且对应字母符合则继续以此方向搜索下一个单词字母 
	if(a>=1&&a<=n&&b>=1&&b<=n&&c<=6&&ch[a][b]==word[c])
		dfs(a+xx[d],b+yy[d],c+1,d);
	return 0; 
}
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
			cin>>ch[i][j];	//输入单词方阵 
	}
	for(int i=1;i<=n;i++)	//遍历一遍方阵							
	{
		for(int j=1;j<=n;j++)
		{
			if(ch[i][j]=='y')	//若找到首字符'y' 
			{
				for(int k=0;k<8;k++)	//遍历,向八个方向搜索 
					dfs(i,j,0,k);
			}
		}
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(vis[i][j])	//如果标记为true,则表示为单词字母,输出 
				cout<<ch[i][j];
			else	//若标记为false,则表示为'*' 
				cout<<'*';
		}
		cout<<endl;	//每行输完后就换行 
	} 
	return 0;
}

第二种:暴力模拟

1、用数组a[105][105]表示表示输入的方阵字符,数组b[105][105]表示输出的方阵字符。

2、输出的方阵字符数组b[105][105]先全部用“ * ”替换掉,然后把八个方向的情况一一列出来即可,代码量比较多,200多行,但思路很简单。

代码如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std; 
int main() 
{
	int n;
	cin>>n;
	//数组a[105][105]表示输入的字符,数组b[105][105]表示输出的字符 
	char a[105][105],b[105][105];	
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			cin>>a[i][j];
			b[i][j]='*';	//输出的方阵字符先全部用'*'替换掉 
		}
	}
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			if(a[i][j]=='y')	//从正左往正右 
			{
				if(a[i][j+1]=='i')
				{
					if(a[i][j+2]=='z')
					{
						if(a[i][j+3]=='h')
						{
							if(a[i][j+4]=='o')
							{
								if(a[i][j+5]=='n')
								{
									if(a[i][j+6]=='g')
									{
										b[i][j]=a[i][j];
										b[i][j+1]=a[i][j+1];
										b[i][j+2]=a[i][j+2];
										b[i][j+3]=a[i][j+3];
										b[i][j+4]=a[i][j+4];
										b[i][j+5]=a[i][j+5];
										b[i][j+6]=a[i][j+6];
									}
								}
							}
						}
					}
				}
			}
			if(a[i][j]=='y')	//从正右往正左 
			{
				if(a[i][j-1]=='i')
				{
					if(a[i][j-2]=='z')
					{
						if(a[i][j-3]=='h')
						{
							if(a[i][j-4]=='o')
							{
								if(a[i][j-5]=='n')
								{
									if(a[i][j-6]=='g')
									{
										b[i][j]=a[i][j];
										b[i][j-1]=a[i][j-1];
										b[i][j-2]=a[i][j-2];
										b[i][j-3]=a[i][j-3];
										b[i][j-4]=a[i][j-4];
										b[i][j-5]=a[i][j-5];
										b[i][j-6]=a[i][j-6];
									}
								}
							}
						}
					}
				}
			}
			if(a[i][j]=='y')	//从上往下 
			{
				if(a[i+1][j]=='i')
				{
					if(a[i+2][j]=='z')
					{
						if(a[i+3][j]=='h')
						{
							if(a[i+4][j]=='o')
							{
								if(a[i+5][j]=='n')
								{
									if(a[i+6][j]=='g')
									{
										b[i][j]=a[i][j];
										b[i+1][j]=a[i+1][j];
										b[i+2][j]=a[i+2][j];
										b[i+3][j]=a[i+3][j];
										b[i+4][j]=a[i+4][j];
										b[i+5][j]=a[i+5][j];
										b[i+6][j]=a[i+6][j];
									}
								}
							}
						}
					}
				}
			}
			if(a[i][j]=='y')	//从下往上 
			{
				if(a[i-1][j]=='i')
				{
					if(a[i-2][j]=='z')
					{
						if(a[i-3][j]=='h')
						{
							if(a[i-4][j]=='o')
							{
								if(a[i-5][j]=='n')
								{
									if(a[i-6][j]=='g')
									{
										b[i][j]=a[i][j];
										b[i-1][j]=a[i-1][j];
										b[i-2][j]=a[i-2][j];
										b[i-3][j]=a[i-3][j];
										b[i-4][j]=a[i-4][j];
										b[i-5][j]=a[i-5][j];
										b[i-6][j]=a[i-6][j];
									}
								}
							}
						}
					}
				}
			}
			if(a[i][j]=='y')	//从左上往右下 
			{
				if(a[i+1][j+1]=='i')
				{
					if(a[i+2][j+2]=='z')
					{
						if(a[i+3][j+3]=='h')
						{
							if(a[i+4][j+4]=='o')
							{
								if(a[i+5][j+5]=='n')
								{
									if(a[i+6][j+6]=='g')
									{
										b[i][j]=a[i][j];
										b[i+1][j+1]=a[i+1][j+1];
										b[i+2][j+2]=a[i+2][j+2];
										b[i+3][j+3]=a[i+3][j+3];
										b[i+4][j+4]=a[i+4][j+4];
										b[i+5][j+5]=a[i+5][j+5];
										b[i+6][j+6]=a[i+6][j+6];
									}
								}
							}
						}
					}
				}
			}
			if(a[i][j]=='y')	//从右下往左上 
			{
				if(a[i-1][j-1]=='i')
				{
					if(a[i-2][j-2]=='z')
					{
						if(a[i-3][j-3]=='h')
						{
							if(a[i-4][j-4]=='o')
							{
								if(a[i-5][j-5]=='n')
								{
									if(a[i-6][j-6]=='g')
									{
										b[i][j]=a[i][j];
										b[i-1][j-1]=a[i-1][j-1];
										b[i-2][j-2]=a[i-2][j-2];
										b[i-3][j-3]=a[i-3][j-3];
										b[i-4][j-4]=a[i-4][j-4];
										b[i-5][j-5]=a[i-5][j-5];
										b[i-6][j-6]=a[i-6][j-6];
									}
								}
							}
						}
					}
				}
			}
			if(a[i][j]=='y')	//从左下往右上 
			{
				if(a[i-1][j+1]=='i')
				{
					if(a[i-2][j+2]=='z')
					{
						if(a[i-3][j+3]=='h')
						{
							if(a[i-4][j+4]=='o')
							{
								if(a[i-5][j+5]=='n')
								{
									if(a[i-6][j+6]=='g')
									{
										b[i][j]=a[i][j];
										b[i-1][j+1]=a[i-1][j+1];
										b[i-2][j+2]=a[i-2][j+2];
										b[i-3][j+3]=a[i-3][j+3];
										b[i-4][j+4]=a[i-4][j+4];
										b[i-5][j+5]=a[i-5][j+5];
										b[i-6][j+6]=a[i-6][j+6];
									}
								}
							}
						}
					}
				}
			}
			if(a[i][j]=='y')	//从右上往左下 
			{
				if(a[i+1][j-1]=='i')
				{
					if(a[i+2][j-2]=='z')
					{
						if(a[i+3][j-3]=='h')
						{
							if(a[i+4][j-4]=='o')
							{
								if(a[i+5][j-5]=='n')
								{
									if(a[i+6][j-6]=='g')
									{
										b[i][j]=a[i][j];
										b[i+1][j-1]=a[i+1][j-1];
										b[i+2][j-2]=a[i+2][j-2];
										b[i+3][j-3]=a[i+3][j-3];
										b[i+4][j-4]=a[i+4][j-4];
										b[i+5][j-5]=a[i+5][j-5];
										b[i+6][j-6]=a[i+6][j-6];
									}
								}
							}
						}
					}
				}
			}
		}
	}
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
			cout<<b[i][j];
		cout<<endl;
	} 
	return 0;
}

你可能感兴趣的:(算法)