0
点赞
收藏
分享

微信扫一扫

【洛谷主题库】P7995 [USACO21DEC] Walking Home B

凶猛的小白兔 2022-04-27 阅读 40
c++dfs

考场上唯一会的题目。


显然是 dfs 爆搜。
准备四个参数:行、列、可转向次数、当前方向,然后分四种情况:

  • 向右,改变方向
  • 向右,不改变方向
  • 向下,改变方向
  • 向下,不改变方向

一个一个做即可。

然而不知怎的(大概 USACO 评测机波动)A 了。
这是考场 AC 代码 结果发现在尼姑 TLE 了。
于是开始了劲爆卡常。
好吧其实不止卡常,还有剪枝。


如果把一些条件(如越界、不符合要求的格子、到达终点、改变方向次数等)放在函数开头,则会多递归一次,增加常数,从而导致 TLE。
因此我们要在递归前判断。
部分代码:

void dfs(int x,int y,int k,int fx)
{
	if(fx==2)//两种情况(向下、向右)
	{
		if(x+1<=n&&!a[x+1][y])//不改变方向
		{
			if(x+1==n&&y==n) ++ans;//到达终点,下同
			else dfs(x+1,y,k,2);
		}
		if(y+1<=n&&k&&!a[x][y+1])//改变方向
		{
			if(x==n&&y+1==n) ++ans;
			else dfs(x,y+1,x==1&&y==1?k:k-1,1);//起点的转向不计入 k 内,下同
		}
	}
	else
	{
		if(y+1<=n&&!a[x][y+1])//不改变方向
		{
			if(x==n&&y+1==n) ++ans;
			else dfs(x,y+1,k,1);
		}
		if(x+1<=n&&k&&!a[x+1][y])//改变方向
		{
			if(x+1==n&&y==n) ++ans;
			else dfs(x+1,y,x==1&&y==1?k:k-1,2);
		}
	}
}

AC 记录。

举报

相关推荐

0 条评论