算法提高 智能体系列赛 java 题解

30 篇文章 1 订阅
25 篇文章 1 订阅

资源限制

时间限制: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。


解题思路:

题中提示到要用到搜索,并且题给出的矿点个数很少,所以直接对所有矿点深度搜索,将矿点数全排列,在排好的基础上求最少的步数。

由于每个点均以坐标的形式给出,可以将坐标封装成类,简化对数据的处理。

全排列问题:

全排列问题icon-default.png?t=LA92https://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;
	}
}

提交截图:

 

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值