2022河南省CCPC省赛H题旋转水管

那个绝对不能忘记的题
           ~~~~~~~~~~           重要的题
       ~~~~~~       不能忘记的题
       ~~~~~~       不想忘记的题
               ~~~~~~~~~~~~~~               
             ~~~~~~~~~~~~             是谁
           ~~~~~~~~~~           复活吧!
          ~~~~~~~~~          我的题解

那一天,21回想起了,在旋转水管支配之下的恐怖,还有那被囚禁于牢房中的那份耻辱

我记得我大一的时候写了一会dfs之后感觉dfs肯定超时然后换bfs爆了半天内存剪枝剪到了比赛结束也没发现bfs假了

题解

是一道不怎么难的dfs题, 首先要读懂题意, 然后是考差dfs的熟练度, 能够独立完成这题不看题解说明你的dfs已经入门甚至小成(暴论)
注意题意给出的是起点和终点的x坐标, y坐标分别是2和4
起点的x坐标没必要设置为1, 没有意义当然你要设置为1也无所谓

确定了起点和终点之后进入主题, dfs的状态转移
因为此题有水管的概念, 所以需要引入一个方向的概念, 对于每个方向都有流动的不同方向
对于"L"水管, 如果是左右来的水, 那么只能向上下流动
                    ~~~~~~~~~~~~~~~~~~~                    如果是上下来的水, 那么只能向左右流动
对于"I"水管就简单了, 只能保持原来的方向向前流动
理解了这题的dfs之后还有至关重要的一点, 因为水不会重新走走过的路线, 所以我们要对水流走过的位置进行标记, 那么有标记就有"恢复现场", 因为你的dfs可能就走入不是答案的死胡同, 但死胡同路线可能和正确路线有重合, 恢复现场使其不影响正确路线

代码

我只给dfs的代码, 我希望学弟能够对这题有所思考, 不是一味地抄代码
这是一个很经典的dfs题, 之后数据结构中还会更常使用dfs, 我希望你们能牢记这次坐牢的教训

#define E dfs(u+1,v,'E');
#define W dfs(u-1,v,'W');
#define S dfs(u,v+1,'S');
#define N dfs(u,v-1,'N');
void dfs(ll u,ll v,char dir)
{
	if(u==bx&&v==by)
	{
		ans=1;
		return;
	}
	if(ans) return;
	if(u<1||u>m||v<2||v>3||dist[v][u]) return;
	dist[v][u]=1;

	if(str[v][u]=='I')
	{
		if(dir=='N') N
		if(dir=='S') S
		if(dir=='E') E
		if(dir=='W') W
	}else
	{
		if(dir=='N'||dir=='S') 
		{
			E
			W
		}else
		{
			N
			S
		}
	}
	dist[v][u]=0;
}

你可能感兴趣的:(dfs,深度优先,算法,c++)