题目链接:http://acm.zcmu.edu.cn/JudgeOnline/problem.php?id=2201
思路:建立四个数组U,D,L,R,分别表示四个方位,存储每个节点的上下左右的信息。
然后进行深搜,查找出长度最大的节点,并记录它的长度。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 5050;
char a[maxn][maxn];
int n,m,U[maxn],D[maxn],R[maxn],L[maxn];
void Init()
{
int i,j,tp,l;
for(i=0;i<n;i++)
{
l=-1;
for(j=0;j<m;j++)
{
if(a[i][j]!='.')
{
tp=i*m+j;
L[tp]=l; //l表示上一个节点的位置,上一个节点就是这个节点的左结点
if(l!=-1) R[l]=tp; //上一个节点的右节点就是这个节点的右节点
l=tp; //记录当前的节点状态。
}
}
R[l]=-1; //每一行的最后一个节点的右节点是-1
}
for(j=0;j<m;j++)
{
int u=-1;
for(i=0;i<n;i++)
{
if(a[i][j]!='.')
{
tp=i*m+j;
U[tp]=u; //u表示本节点的上一个节点
if(u!=-1) D[u]=tp; //上一个节点的下节点就是本节点
u=tp; //保存上一个节点的状态
}
}
D[u]=-1; //每列最后一个节点的下节点是-1
}
}
void Delete(int x,int y)
{
int index=x*m+y;
if(U[index]!=-1) D[U[index]]=D[index]; //当index不是最高节点时,index的下一个节点的值变成了当前节点的值,相当于抹去了当前节点。
if(D[index]!=-1) U[D[index]]=U[index];
if(L[index]!=-1) R[L[index]]=R[index];
if(R[index]!=-1) L[R[index]]=L[index];
}
int dfs(int x,int y)
{
Delete(x,y);
int index=x*m+y;
if(a[x][y]=='U')
{
if(U[index]==-1) return 1;
return dfs(U[index]/m,y)+1;
}
else if(a[x][y]=='D')
{
if(D[index]==-1) return 1;
return dfs(D[index]/m,y)+1;
}
else if(a[x][y]=='R')
{
if(R[index]==-1) return 1;
return dfs(x,R[index]%m)+1;
}
else if(a[x][y]=='L')
{
if(L[index]==-1) return 1;
return dfs(x,L[index]%m)+1;
}
}
int main(void)
{
int i,j;
while(cin>>n>>m)
{
for(i=0;i<n;i++) scanf("%s",a[i]);
int cnt=0,mx=-1;
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
if(a[i][j]!='.')
{
Init(); //标记所有点最近的上下左右节点
int len=dfs(i,j);
if(len>mx) mx=len,cnt=1;
else if(len==mx) cnt++;
}
}
}
cout<<mx<<" "<<cnt<<endl;
}
return 0;
}
参考文章:https://blog.csdn.net/sdau20163942/article/details/80348700