难度:普及
题目类型:枚举
提交次数:1
涉及知识:DFS
描述
在一个n*n的字母方阵中内可能包含多个“bdfz”单词。单词在方阵中是沿着同一方向连续摆放的。摆放可沿着8个方向的任一方向,同一单词摆放时不再改变方向,单词与单词之间有可能共用字母。
输出时,将不是单词的字母用“.”代替,以突出显示单词。
输入第一行输入一个数n。(7<=n<=10)。
第二行开始输入n*n的字母矩阵。输出突出显示单词的n*n矩阵。
样例输入
6 qybzhz gbdfzk bwfdxh odzfdb zffrbb fdzzzo
样例输出
..b... .bdfz. b.f... .dzfdb ..f... ...z..
代码:
1 #include<iostream> 2 using namespace std; 3 int n; 4 char a[11][11]; 5 char b[11][11]; 6 int dirx[8] = {-1, -1, -1, 0, 0, 1, 1, 1}; 7 int diry[8] = {0, -1, 1, 1, -1, 0, -1, 1}; 8 char s[5] = {'0','b','d','f','z'}; 9 10 void dfs(int i, int j, int step, int dir){ 11 if(step == 4){ 12 for(int k = 0; k <= 3; k++) 13 b[i-k*dirx[dir]][j-k*diry[dir]] = a[i-k*dirx[dir]][j-k*diry[dir]]; 14 return; 15 } 16 else if(step == 1){ 17 for(int k = 0; k < 8; k++){ 18 //cout<<a[i+dirx[k]][j+diry[k]]<<endl; 19 if(a[i+dirx[k]][j+diry[k]]==s[step+1]){ 20 21 dfs(i+dirx[k], j+diry[k], step+1, k); 22 } 23 } 24 25 } 26 else{ 27 if(a[i+dirx[dir]][j+diry[dir]]==s[step+1]) 28 dfs(i+dirx[dir],j+diry[dir],step+1, dir); 29 } 30 } 31 32 int main(){ 33 cin>>n; 34 int i, j; 35 for(i = 1; i <= n; i++) 36 for(j = 1; j <= n; j++){ 37 cin>>a[i][j]; 38 } 39 for(i = 1; i <= n; i++) 40 for(j = 1; j <= n; j++){ 41 if(a[i][j]=='b') 42 dfs(i,j,1,0); 43 } 44 for(i = 1; i <= n; i++){ 45 for(j = 1; j <= n; j++) 46 if(b[i][j]==0) cout<<"."; 47 else cout<<b[i][j]; 48 cout<<endl; 49 } 50 return 0; 51 }
备注:
议事会上写的。
不考虑代码复杂(长)度的话,直接枚举就行了。不过尊重它作为一道老师让我们练DFS的题,我还是费了一些脑筋思考怎么DFS。。其实本质还是枚举。
dfs有四个参量i,j为坐标,step为第几个数,dir为方向,因为一个单词中间不能换方向。对于b来说,它可以往八个方向“发展”,即为k。但到了step2方向就确定了,只能朝这个方向走。
判断每一步是否合法就用到了s数组构造的映射。这个是自己想到的,之后发现好多人生写DFS都是这么用的。。
注意是step==4的时候为边界条件。本质上我一般用的dfs格式都是在当前位置判断下一个是否符合条件,标记。所以这里不是step==5。到了边界条件后就回溯,标记。。
输入输出遇到奇怪的问题是因为智障把数据类型写成了int,还百思不得其解了半天,把输入那三行来回来去看了半天,啥也没看出来。直到瞄了一眼全局变量。。