B4097 [CSP-X2022 山东] 移动棋子
欢迎报名洛谷网校,期待和大家一起进步!
我们考虑最多使用
-
不使用翻转
如果x \le y ,我们可以直接用操作1 不断加1 走到y 。所需步数就是y - x 。 -
使用一次翻转
思路是先做若干次操作1 ,使得当前位置变为x + t (其中t 为所做的加1 次数),然后使用操作2 将位置变成-(x+t) ;接着再利用操作1 从- (x+t) 走到y (假设这里用了u 次操作1 。注意加1 操作只能使数字增大,因此要求- (x+t) \le y )。
分析这样做的操作步数:-
- 总步数为:
t + 1 + (y + x + t) = 1 + x + y + 2t 。 - 由于
u\geq 0 ,因此需要选择最小的t 满足x+t \ge -y 。即当x+t 不足够大时,需要继续加1 后再翻转。 - 最佳选择是令
t = \max(0,-y - x) ,此时总操作步数为1 + x + y + 2\max(0,-y - x) 。
-
-
使用两次翻转
当x > y 时(比如正数向较小正数走,或两负数中较大者向较小者走),直接加1 无法到达目标,此时可以先翻转,再加1 ,最后再翻转。 具体过程:- 第一步:直接用操作
2 将x 翻转为-x (1 步); - 接下来用操作
1 从-x 加到某个数,然后再翻转回来,使得最终正好到达y 。 - 分析可得,这样做的最少操作步数为
(x - y) + 2 。
- 第一步:直接用操作
最后,我们根据
参考代码(关键部分):
// 方案 1:使用 0 次翻转
if(x <= y){
cand0 = y - x; // 直接加 1 即可到达
ans = cand0;
}
// 方案 2:使用 1 次翻转
// 先做 t 次加 1, t 最小满足 x+t >= -y
long long t = 0;
if(x < -y) {
t = -y - x;
}
cand1 = 1 + x + y + 2*t; // 总步数:t 次加 1, 1 次翻转, 再 (y+x+t) 次加 1
ans = min(ans, cand1);
// 方案3:使用 2 次翻转(适用于 x > y 的情况)
if(x > y) {
cand2 = (x - y) + 2;
ans = min(ans, cand2);
}