#include<iostream>
#include<string>
#include<cstring>
using namespace std;
int cnt = 0,k=0,l=0,n,fndx[10000],fndy[10000],color[1000][1000], tmpr[100000], tmpc[100000];
int dx[8] = { 1,1,0,-1,-1,- 1,0,1 }, dy[8] = { 0,-1,-1,-1,0,1,1,1 };//从右开始顺时针
string ab[105],word="yizhong";//字母方阵
void dfs(int r, int c, int i)
{
if (ab[r][c] != word[i])
return;
if (i>=2&&((tmpr[i - 2] - r)*(tmpc[i - 1] - c) != (tmpr[i - 1] - r)*(tmpc[i - 2] - c)))//不沿着一条直线
return;
if (i == 6)
{
tmpr[i] = r;
tmpc[i] = c;
for (int m = i; m >= i-6; m--)//(l-1)-x+1=7
{
color[tmpr[m]][tmpc[m]]=1;
}//把路径上暂时染色的全部真正染色
return;
}
int j;
for(j=0;j<8;j++)
{
tmpr[i] = r;
tmpc[i] = c;//判断染色的顺序,即路径,以判断是否在一条直线上染色
if (r + dy[j] >= 0 && r + dy[j] < n && c + dx[j] >= 0 && c + dx[j] < n)
{
dfs(r + dy[j], c + dx[j], i + 1);
}
}
}
int main()
{
memset(color, 0, sizeof(color));
int i, j,m=0;
cin >> n;
getchar();
for (i = 0; i < n; i++)
{
getline(cin,ab[i]);
for (j = 0; j < n; j++)
{
if (ab[i][j] == 'y')
{
fndx[k] = j;
fndy[k] = i;
k++;
}
}
}
for ( i = 0; i < k; i++)
{
dfs(fndy[i],fndx[i],0);
}
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
if (color[i][j]==1)
{
cout << ab[i][j];
}
else
cout << "*";
}
cout << endl;
}
}
总结:
1.访问过的节点习惯上用全局数组color或vis命名,若题目是在坐标中搜索,则数组为多维数组,如本题中为二维数组;
2.本题中每次递归只修改了路径,而代表路径起始值的i是dfs的参数,而不是全局变量,所以在不同分支搜索中每次搜索会覆盖数组的值,所以不需要回溯。
3.坐标系中通过斜率判断方向是否一致。
4.洛谷使用unix系统,该系统中回车代表\r\m,需要用两个getchar()才能消掉。