题解:P4368 [Code+#4] 喵呜

题目传送门

看到数据范围 \(n,h ≤\) \(10^{15}\)的时候就感觉不对了,怎么会如!此!之!大!

后来才反应这本质是一道数学题

感觉可以重开了(* ̄(エ) ̄)

(下面有骗分方法呦)

解题思路

本蒟蒻第一个想到的是暴力搜索,但是这铁定要TLE,所以我们要改善思路,可不可以优化一下呢?

答案就是数学。

先想一下,我们如何让小猫跳到目标地点上?

构建出一个平面坐标系,不难想到每次移动,横坐标都会变化\(a个单位\),纵坐标都会变化\(b个单位\),所以只有当初始坐标与目标坐标的横坐标之差为 a 的整数倍,且纵坐标只差为 b 的整数倍时,才有可能到达目标地点。

我们可以设小猫当前位置为 $(x,y) $,由题可知:

\(y\leq h\),可以水平移动a,那么竖直方向坐标会减少\(b\),坐标会变成 \((x-a,y-b)\) 或者 \((x+a,y-b)\)

\(y \geq h-b\),也可以水平移动a,竖直方向坐标会增加\(b\),坐标会变成 \((x-a,y+b)\) 或者 \((x+a,y+b)\)

综上,一共会有四种移动情况。


那是不是这样我们就可以开始构造代码了呢? \(NONONO\)

我们还忘了另一个重要条件,就是横、纵坐标要同时达到目标

有了这两个条件,我们可以得到下面这段代码

if( (x-1) % a == 0 && (y-1) % b == 0){
	if( ( (x-1) / a - (y-1) / b ) % 2 == 0){
	         ......
		//表示满足条件,可以到达我们的目标坐标
	}
}

现在我们就可以开始着手构造代码了

1,首先读入数据(废话

2,然后开始判断方向,这边建议开一个方向数组,再判断

if(u%a==0) m[0][0]=r/a;
else m[0][0]=-1;

if(x%a==0) m[0][0]=x/a;
else m[0][0]=-1;

if(u%a==0) m[0][0]=u/a;
else m[0][0]=-1;

if(y%a==0) m[0][0]=y/a;
else m[0][0]=-1;

(判断上下左右四个方向哪里可以走)

3,然后开始模拟,记住,跳的次数必须是2的倍数

注意:在向左和向右走的时候会给向上下方向两个回合的迂回时间,所以在手动模拟的时候发生到不了的情况可能只是无法同时到达,想通了就简单了。

4,再判断在两个坐标轴上的两种走法中的四个组合中,两者步数差是否是偶数。如果是偶数,就取总步数大的那个

5,得出结果取最小值就好啦。

代码比较简单,就不在这里展示了,想要看完整代码可以看看前面大佬的题解

骗分

1,直接输出-1,可以得到20分

2,暴力递归,预期得分在25~35左右

3,DFS或者BFS搜索,大概在60分左右

正文结束


已优化,审核大大求过!!!

posted @ 2025-08-11 15:23  Rookie青果  阅读(11)  评论(0)    收藏  举报