题解: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分左右
正文结束
已优化,审核大大求过!!!

浙公网安备 33010602011771号