资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
zsyzgu是一个弱菜,尽管如此他还是参加了智能体系列赛。智能体系列赛的问题经简化后是这样的,有一只猴子和一些矿点,知道他们在平面上的坐标,这只猴子要经过这些矿点至少一次。假设这只猴子从点A走到点B所要花费的步数是这两个点的曼哈顿距离(即|A.x-B.x|+|A.y-B.y|),问这只猴子经过这些矿点至少一次所需的最少步数。
系列赛中的许多选手都用了贪心的策略,即每次都到最近的没经过的矿点去。但zsyzgu的思路是搜索,这也是他能够摆脱垫底命运获得纪念版T-shirt的原因。
输入格式
第一行两个数表示猴子的坐标;
第二行一个数n表示矿点数;
接下来n行每行两个数表示每个矿点的坐标。
输出格式
一行一个数表示最少步数。
样例输入
0 0
4
0 1
0 2
0 3
0 -2
样例输出
7
数据规模和约定
对于100%的数据:1<=n<=10,横纵坐标都是整数,其的绝对值<=10000。
解题思路:
题中提示到要用到搜索,并且题给出的矿点个数很少,所以直接对所有矿点深度搜索,将矿点数全排列,在排好的基础上求最少的步数。
由于每个点均以坐标的形式给出,可以将坐标封装成类,简化对数据的处理。
全排列问题:
全排列问题https://blog.csdn.net/weixin_48898946/article/details/121589155
java代码:
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] split = br.readLine().split(" ");
int x = Integer.parseInt(split[0]);
int y = Integer.parseInt(split[1]);
Loca1179 start = new Loca1179(x, y);//起始点坐标
int n = Integer.parseInt(br.readLine());
Loca1179 []couple = new Loca1179[n + 1];//需要途径的矿点坐标数
for(int i = 1; i <= n; i++) {
split = br.readLine().split(" ");
x = Integer.parseInt(split[0]);
y = Integer.parseInt(split[1]);
couple[i] = new Loca1179(x, y);
}
Temp1179 obj = new Temp1179(start, n, couple);
obj.dfs(1);
System.out.println(obj.ans);
}
}
class Temp1179{
Loca1179 start;//起始坐标
int n;//待经过的点数
Loca1179 []couple;//矿点的坐标
boolean []vis;//标志某一矿点是否被访问过
List<Integer> list = new ArrayList<>();//存放实时经过的矿点顺序
int ans = Integer.MAX_VALUE;//开始路径顶为“无穷大”
int sum = 0;
public Temp1179(Loca1179 start, int n, Loca1179[] couple) {
this.start = start;
this.n = n;
this.couple = couple;
vis = new boolean[n + 1];
}
public void dfs(int step) {
if(step > n) {
compare();//比较每次所需的累积距离
return;
}
for(int i = 1; i <= n; i++) {
if(!vis[i]) {
vis[i] = true;
list.add(i);
dfs(step + 1);
vis[i] = false;//回溯
list.remove(list.size() - 1);
}
}
}
public void compare() {
sum = 0;
sum += Math.abs(start.x - couple[list.get(0)].x) + Math.abs(start.y - couple[list.get(0)].y);//起始点到第一个矿点
for(int i = 1; i < list.size(); i++) {
sum += Math.abs(couple[list.get(i)].x - couple[list.get(i - 1)].x) + Math.abs(couple[list.get(i)].y - couple[list.get(i - 1)].y);
}
if(sum < ans) {
ans = sum;
}
}
}
class Loca1179{//坐标类
int x;
int y;
public Loca1179(int x, int y) {
this.x = x;
this.y = y;
}
}
提交截图: