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;
}
覺得寫的不錯的話, 點個贊吧~