算法提高 智能体系列赛

资源限制
内存限制: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;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值