题解 P1560 【[USACO5.2]蜗牛的旅行Snail Trails】

一发过样例、题目,真开森!

咳咳,进入正题
其实这题并没有想象中的复杂,就是一个智障的大爆搜,我感觉我都没有加上什么优化,然后就 (AC) 了。

我用的有点像是记忆化搜索,然而事实上可以不这么用。
每次搜索路径时,我们就一条道走到黑,不撞南墙不回头,然后在遇到障碍或边界时,枚举其余的方向,再碰到自己走过的路径便停下来,开始回溯
(Code:)

#include <iostream>
#include <cstdio>
using namespace std;
bool book[121][121];
int n,b,ans=0;
int a[121][121],f[121][121][5][2]; 
int t1[5]={0,0,1,0,-1};
int t2[5]={0,1,0,-1,0};
int dfs(int x,int y,int move); 
bool check(int x,int y);
int main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);	 
	scanf("%d %d",&n,&b);
	for(int i=1;i<=b;++i)
	{
		char ch;int num;
		cin>>ch>>num;
		a[num][ch-'A'+1]=1; //在地图上标记出障碍
	} 
	printf("%d",max(dfs(1,1,1),dfs(1,1,2))); //注意,从起点出发的时候,有两条路可以走,右边和下边
	return 0;
} 
bool check(int x,int y)  //判断函数,判断现在是否遇到了障碍、边界或者自己走过的路
{
	if(x>n || x<1 || y>n || y<1 || a[x][y] || book[x][y]) return true;
	return false; 
}
int dfs(int x,int y,int move) //x是横坐标,y是纵坐标,move是移动的方向:1表示右,2表示下,3表示左,4表示上
{
	int d=1;  //记录每个方向的最大值
	book[x][y]=true; //标记这个点已经来过
	int tx=x+t1[move],ty=y+t2[move]; //判断目前移动的方向
	if(!book[tx][ty]) //如果没来过这个点,才能进行下面的判断
	{
		if(check(tx,ty))  //检测是否合法
		{
			for(int i=1;i<=4;++i)//如果不合法,那么选择一条可以走的路
			{
				tx=x+t1[i]; ty=y+t2[i];
				if(!check(tx,ty)) //下一个点也必须合法
					d=max(d,dfs(tx,ty,i)+1); 
			}
		}
		else //如果合法,那么就继续往下走
			d=dfs(tx,ty,move)+1; //统计走过的个数时注意加上自己本身这个节点
	}
	book[x][y]=false; //无路可走后,把这个点的标记删掉
	return d; //返回在x,y能走的最大节点数
}
原文地址:https://www.cnblogs.com/Call-me-zhz/p/11287372.html