CF10518M.Too Easy

CF10518M.Too Easy

Lionlnuc
Lionlnuc Lv4

题目链接: Problem - M - Codeforces
题意:
有一个无限大的二维网格,你从坐标  出发,要到达坐标 (也可能是同一个点)。每一步你可以向左、右、上、下走一格。你的任务是找出到达目标坐标所需的最少步数。你不能连续朝同一个方向走超过  步。
思路:
先不看题目的限制,从一个坐标到另一个坐标需要走的步数为 ,这里 s 和 t 值的大小是不确定的所以取绝对值,高级一点就叫曼哈顿距离。
现在题目增加了一个不能在同一个方向连续走超过 步,其实就是我连续走 k 步然后换个方向走一步,然后再回来再走 k 步,这样循环下去。我们可以把方向分成主方向(步数多)和次方向。
这样在主方向最多可以走 次方向步数 步,这时候是没走多余步数的。
现在就可以分成两种情况:

  1. 主方向次方向 这种情况说明主方向可以被次方向合理分割,这样就直接输出曼哈顿距离即可。
  2. 主方向次方向 这时候次方向已经不够了,所以需要走额外的步数来调整。超出的步数 主方向次方向,所以此时需要向无关方向走 1 步,朝主方向走 k 步,再向无关方向反方向走一步 (回到原位),再朝主方向走 k 步。这样是一个循环,所以需要 个循环,每个循环额外花费 2 步。
    所以额外步数的计算可以用 ceil 向上取整去计算也可以使用 主方向次方向 计算。

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
void solve()
{
int x1,x2,y1,y2,k;
cin>>x1>>y1>>x2>>y2>>k;
int x=abs(x1-x2),y=abs(y1-y2);
if(x<y)swap(x,y);
if(x<=(y+1)*k)cout<<x+y<<endl;
else{
int step=(x-(y+1)*k+2*k-1)/(2*k);
cout<<x+y+step*2<<endl;
}
}
signed main(){
IOS
int t;
cin>>t;
//int t=1;
while(t--)
{
solve();
}
}
  • 标题: CF10518M.Too Easy
  • 作者: Lionlnuc
  • 创建于 : 2026-02-03 00:00:00
  • 更新于 : 2026-02-03 00:00:00
  • 链接: https://lionlnuc.github.io/2026/02/03/CF10518M.Too Easy/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论
目录
CF10518M.Too Easy