一发过样例、题目,真开森!
咳咳,进入正题
其实这题并没有想象中的复杂,就是一个智障的大爆搜,我感觉我都没有加上什么优化,然后就 (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能走的最大节点数
}