藍橋杯-移動距離(最簡單的寫法)

小程xy發表於2024-05-13

X星球居民小區的樓房全是一樣的,並且按矩陣樣式排列。

其樓房的編號為 1,2,3…當排滿一行時,從下一行相鄰的樓往反方向排號。

比如:當小區排號寬度為 6 時,開始情形如下:

1 2 3 4 5 6
12 11 10 9 8 7
13 14 15 .....
我們的問題是:已知了兩個樓號 m 和 n,需要求出它們之間的最短移動距離(不能斜線方向移動)。

輸入格式

輸入共一行,包含三個整數 w,m,n,w 為排號寬度,m,n 為待計算的樓號。

輸出格式

輸出一個整數,表示 m,n 兩樓間最短移動距離。

資料範圍

1≤w,m,n≤10000,

輸入樣例:

6 8 2

輸出樣例:

4

題解:

  • 把要求的兩點的座標求出來
  • 橫縱座標都從0開始

程式碼中的 n --, m --能省去很多邊界特殊情況

1 2 3 4 5 6
12 11 10 9 8 7
13 14 15 ....

邊界分析:
這個中如果n沒有減一, 那麼 6的橫座標就變成了 n/w = 1, 而 1、2、3、4、5的橫座標是 n/w = 0, 顯然 6 的橫座標是0, 或者[1,5]的橫座標是1
再比如6的縱座標是 n%w = 0, 顯然如果縱座標是從0開始的, 6的縱座標應該是5, 如果縱座標是從1開始的, 6的縱座標就應該是6


但是如果我們對 n減一, m減一, 就可以不用處理上面的特殊情況

上面的邊界情況看上去不復雜, 但處理起來並不簡單, 不信你自己嘗試下

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int w, n, m; cin >> w >> n >> m;
    n --, m --;
    
    int xn = n / w, yn = n % w, xm = m / w, ym = m % w;
    
    if (xn % 2 != 0) yn = w - yn - 1; // 當時奇數行的時候:  n % w算出來的是從右往左的座標, 我們要把它的縱座標轉換成從左往右的座標
    if (xm % 2 != 0) ym = w - ym - 1;

    cout << abs(xn - xm) + abs(yn - ym) << endl;
    return 0;
}

覺得寫的不錯的話, 點個贊吧~