AcWing 1902. 马拉松(枚举)
【題目描述】
農夫約翰對他的奶牛們的健康狀況并不滿意,于是給他的奶牛們報名了各種健身活動。
他最喜歡的奶牛貝茜被報名參加了一個跑步班。
在那里,她有希望在一場馬拉松比賽中穿越約翰農場所在的城市的市中心。
馬拉松線路由NNN個檢查點(編號1~N1\sim N1~N)指定。
檢查點111是起點,檢查點NNN是終點,貝茜要按順序經過每個檢查點。
但是貝茜十分懶惰,所以她決定跳過其中一個檢查點,以縮短她的整個行程。
但是,她不能跳過檢查點111和檢查點NNN,因為這太容易被人發現了。
在她可以跳過一個檢查點的情況下,請確定她需要行進的最短距離。
由于該路線設置在市中心,街道呈網格狀交錯,因此兩個檢查站點(x1,y1)(x_1,y_1)(x1?,y1?)與(x2,y2)(x_2,y_2)(x2?,y2?)之間的距離應該為∣x1?x2∣+∣y1?y2∣|x_1-x_2|+|y_1-y_2|∣x1??x2?∣+∣y1??y2?∣。
【輸入格式】
第一行包含整數NNN。
接下來NNN行,每行包含兩個整數x,yx,yx,y,表示一個檢查點的橫縱坐標。檢查點按1~N1\sim N1~N的順序給出。
請注意,比賽線路可能存在交叉,在同一物理位置出現多個檢查點。
當貝茜跳過這樣一個檢查點時,她只跳過其中一個檢查點,而不是跳過這個位置上的所有檢查點。
【輸出格式】
輸出貝茜可以跳過一個檢查點的情況下,需要行進的最短距離。
【數據范圍】
3≤N≤1053≤N≤10^53≤N≤105
?1000≤x,y≤1000-1000≤x,y≤1000?1000≤x,y≤1000
【輸入樣例】
4 0 0 8 3 11 -1 10 0【輸出樣例】
14【樣例解釋】
最佳方案是跳過(8,3)(8,3)(8,3)。
【分析】
首先我們求出從111走到nnn的總距離,然后枚舉跳過的點i(2≤i≤n?1)i(2\le i\le n-1)i(2≤i≤n?1),求出跳過某個點能夠減少的距離的最大值maxdmaxdmaxd。如何求出跳過某個點能夠減少的距離呢?假設跳過的點為iii,原本所需的距離為dis(i?1,i)+dis(i,i+1)dis(i-1,i)+dis(i,i+1)dis(i?1,i)+dis(i,i+1),跳過點iii后也就是從i?1i-1i?1直接走到i+1i+1i+1,距離為dis(i?1,i+1)dis(i-1,i+1)dis(i?1,i+1),因此跳過點iii能夠減少的距離即為dis(i?1,i)+dis(i,i+1)?dis(i?1,i+1)dis(i-1,i)+dis(i,i+1)-dis(i-1,i+1)dis(i?1,i)+dis(i,i+1)?dis(i?1,i+1)。最后的結果即為sum?maxdsum-maxdsum?maxd。
【代碼】
#include <iostream> #include <cstring> #include <algorithm> #include <cmath> #define X first #define Y second using namespace std;typedef pair<int, int> PII; const int N = 100010; PII p[N]; int n, sum, maxd;//sum為1~n的總路程,maxd為去掉某個點能夠減少的路程的最大值int get(PII a, PII b) {return abs(a.X - b.X) + abs(a.Y - b.Y); }int main() {cin >> n;for (int i = 0; i < n; i++){cin >> p[i].X >> p[i].Y;if (i) sum += get(p[i], p[i - 1]);}for (int i = 1; i < n - 1; i++){PII a = p[i - 1], b = p[i], c = p[i + 1];maxd = max(maxd, get(a, b) + get(b, c) - get(a, c));}cout << sum - maxd << endl;return 0; }總結
以上是生活随笔為你收集整理的AcWing 1902. 马拉松(枚举)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C语言—— 闰年判断
- 下一篇: 2 nagios 客户端软件安装及配置