资源限制
内存限制:256.0MB C/C++时间限制:1.0s Java时间限制:3.0s Python时间限制:5.0s
问题描述
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。
将坐标封装成类,由于规模不大对每个坐标进行全排序计算每一个排序的路线总长度,在dfs判断结束时用ans记录路径最短
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]);
Local start=new Local(x,y);
int n=Integer.parseInt(br.readLine());
Local[] local=new Local[n+1];
for(int i=1;i<=n;i++) {
split=br.readLine().split(" ");
x=Integer.parseInt(split[0]);
y=Integer.parseInt(split[1]);
local[i]=new Local(x,y);
}
Temp obj=new Temp(start,n,local);
obj.dfs(1);
System.out.print(obj.ans);
}
}
class Temp{
Local start;//起始坐标
int n;//待经过的点数
Local []local;//矿点的坐标
boolean []vis;//标志某一矿点是否被访问过
List<Integer>list=new ArrayList<>();//存放实时经过的矿点顺序
int ans=Integer.MAX_VALUE;//开始路径顶为“无穷大”
int sum=0;
public Temp(Local start,int n,Local[] local) {
this.start=start;
this.n=n;
this.local=local;
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-local[list.get(0)].x)+Math.abs(start.y-local[list.get(0)].y);
for(int i=1;i<list.size();i++) {
sum+=Math.abs(local[list.get(i)].x-local[list.get(i-1)].x)+Math.abs(local[list.get(i)].y-local[list.get(i-1)].y);
}
if(sum<ans) {
ans=sum;
}
}
}
class Local{
int x;
int y;
public Local(int x,int y) {
this.x=x;
this.y=y;
}
}