#P1930. 第1题-小美移瓶子
-
1000ms
Tried: 344
Accepted: 71
Difficulty: 4
所属公司 :
美团
时间 :2024年8月24日
第1题-小美移瓶子
思路:枚举
除了第一次从(a,b)出发外,后面均是从(c,d)出发再回到(c,d),所以需要确定我们去的第一个点是哪个。枚举该点并计算其它点到(c,d)的路径总和即可。
代码
python
import sys
a, b, c, d = map(int, input().split())
n = int(input())
X = [0] * n
Y = [0] * n
ans = 0
idx = -1
mx = sys.maxsize
for i in range(n):
# 读取每个点的坐标
X[i], Y[i] = map(int, input().split())
x, y = X[i], Y[i]
# 计算从 (c, d) 到当前点的距离
t = abs(x - c) + abs(y - d)
# 计算从 (a, b) 到当前点的距离减去从 (c, d) 到当前点的距离
dist = abs(x - a) + abs(y - b) - t
# 找到从 (a, b) 出发到该点可以替换的最大距离减小量
if idx == -1 or dist < mx:
idx = i
mx = dist
# 计算从 (c, d) 出发到每个点的总距离
for i in range(n):
x, y = X[i], Y[i]
ans += 2 * (abs(x - c) + abs(y - d))
# 加上从 (a, b) 出发到选定点的距离减小量
ans += mx
print(ans)
C++
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define N 100010
ll a, b, c, d;
ll site_x[N];
ll site_y[N];
int main(){
int n;
cin >> a >> b >> c >> d;
cin >> n;
ll res = 0;
for(int i = 0; i < n; i++){
cin >> site_x[i] >> site_y[i];
res = res + 2*(abs(site_x[i] - c) + abs(site_y[i] - d));
}
ll temp_res = res;
for(int i = 0; i < n; i++){ // 枚举哪个点是ab开始的第一个点
temp_res -= 2*(abs(site_x[i] - c) + abs(site_y[i] - d));
temp_res += (abs(site_x[i] - a) + abs(site_x[i] - c) + abs(site_y[i] - b) + abs(site_y[i] - d));
if(temp_res < res){
res = temp_res;
}
temp_res -= (abs(site_x[i] - a) + abs(site_x[i] - c) + abs(site_y[i] - b) + abs(site_y[i] - d));
temp_res += 2*(abs(site_x[i] - c) + abs(site_y[i] - d));
}
cout << res << endl;
return 0;
}
Java
import java.util.Scanner;
/**
* @Author: sj
* @Date: 2024-08-31
* @Description: 小塔移瓶子
*/
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long a = sc.nextLong();
long b = sc.nextLong();
long c = sc.nextLong();
long d = sc.nextLong();
int n = sc.nextInt();
long[][] bottles = new long[n][2];
long sum = 0;
for(int i = 0; i < n; i++){
bottles[i][0] = sc.nextInt();
sum += Math.abs(bottles[i][0] - c);
bottles[i][1] = sc.nextInt();
sum += Math.abs(bottles[i][1] - d);
}
sum *= 2;
long res = Long.MAX_VALUE;
long dis = 0;
for(int i = 0; i < n; i++){
dis = Math.abs(bottles[i][0] - a) + Math.abs(bottles[i][1] - b);
res = Math.min(res, sum - Math.abs(bottles[i][0] - c) - Math.abs(bottles[i][1] - d) + dis);
}
System.out.println(res);
}
}
题目内容
小美初始位于(a,b)位置,二维平面上有n个瓶子,每个瓶子的位置为(xi,yi),小美每次可以 向上、下、左、右移动一格,每次移动的代价为1,小美需要每次移动到一个瓶子的位置上,然后拿起瓶子把它放到(c,d)位置,每次最多只能拿一个瓶子。请问最少需要多少代价才能把所以瓶子都放到(c,d)位置上。
输入描述
第一行四个整数a,b,c,d(−109≤a,b,c,d≤109),表示小美初始位置和瓶子需要放置的位置。
接下来一行一个整数n(1≤n≤105),表示瓶子的数量。
接下来n行,每行两个整数xi,yi(−10≤xi,yi≤109),表示第i个瓶子的位置。
输出描述
输出一个整数,表示最少需要多少代价。
样例1
输入
0 0 1 1
2
1 0
2 2
输出
6
说明
先移动到(1,0),拿起瓶子,移动到(1,1),放下瓶子,代价为2。
再移动到(2,2),拿起瓶子,移动到(1,1),放下瓶子,代价为4。
样例2
输入
输出