wls正在玩一个寻宝游戏。
宝藏一共有n种,都藏在一个m行m列的网格中。
每种宝藏都恰好有两个。
wls只能沿着网格走(上下左右四个方向)。
他想依次获得1...n类宝藏,然后再以n...1的顺序获得剩下的宝藏。
wls可以从任意点出发。
当wls到达某个宝藏的位置时,他可以选择取或不取这个宝藏。
请问他最少要移动多少距离?
输入描述
第一行两个整数n,m。
接下来nn组,每组两行表示一类宝藏,每行两个整数x,y表示一个宝藏的坐标。
1≤n,m≤100000
1≤x,y≤m
输出描述
一行一个整数表示答案。
样例输入 1
2 10 1 1 2 2 3 3 4 4样例输出 1
10当初做这个题时没想到。我第一次只是想到了每个点去的时候取最小值,然后疯狂WA。
后来题解也是我们要考虑两种情况,但是这两种情况是Min(第一个点去第三个点的距离+第二个点去第四个点的距离,第一个点去第四个点的距离+第二个点去第三个点的距离)。每次都去最小值,加起来就行了。
当时考虑的少了一步。
#include<stdio.h> #include<bits/stdc++.h> #include<iostream> #include<algorithm> #include<string.h> #include<string> #define PI 3.1415926 using namespace std; typedef long long ll; const int maxn = 2e5 + 100; struct node { int x, y; }edge[maxn*2]; int dis(int x, int y, int x1, int y1) { return abs(x - x1) + abs(y - y1); } int main() { //freopen("C://input.txt", "r", stdin); int n, m; scanf("%d%d", &n, &m); for (int i = 1; i <= 2 * n; i++) { scanf("%d%d", &edge[i].x, &edge[i].y); } ll sum = 0; for (int i = 1; i <= 2 * n-2; i += 2) { int mi = dis(edge[i].x, edge[i].y, edge[i + 2].x, edge[i + 2].y)+dis(edge[i+1].x,edge[i+1].y,edge[i+3].x,edge[i+3].y); int mi1 = dis(edge[i].x, edge[i].y, edge[i + 3].x, edge[i + 3].y) + dis(edge[i + 1].x, edge[i + 1].y, edge[i + 2].x, edge[i + 2].y); sum += min(mi, mi1); } sum += dis(edge[2 * n - 1].x, edge[2 * n - 1].y, edge[2 * n].x, edge[2 * n].y); printf("%lld\n", sum); }
2019 CCPC-Wannafly Winter Camp Day4 (Div2, onsite) A 夺宝奇兵 贪心
最新推荐文章于 2021-07-10 11:07:33 发布