1. 程式人生 > >zcmu 2201 (dfs+鄰接表)

zcmu 2201 (dfs+鄰接表)

題目連結: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