Atcoder ABC338 D - Island Tour

Island Tour(岛之旅)

时间限制:2s 内存限制:1024MB

【原题地址】

点击此处跳转至原题

【问题描述】

Atcoder群岛由N个岛屿组成,这些岛屿由N座桥连接。

岛屿编号从1到N,第i座桥(1≤i≤N−1)双向连接岛屿i和i+1,而第N座桥双向连接岛屿N和1。除了过桥,没有办法在岛屿之间旅行。在岛上,定期进行从岛 X1​ 出发并按顺序访问岛X2 ,X3 ,…,XM 的旅游。

旅游团可能会经过不在参观之列的岛屿,并且在旅程期间跨越桥梁的总次数被定义为旅程的长度。更准确地说,ATour是满足以下所有条件的l+1个岛a0 ,a1 ,…,al 的序列,

其长度定义为l:

-对于所有j (0≤j≤l−1),岛aj 和aj+1 通过桥直接连接。

-存在一些0=y1

由于财政困难,群岛将关闭一座桥梁,以减少维护费用。

确定待关闭桥梁的最佳选择时,行程的最小可能长度。

【输入格式】

输入内容由标准输入法提供,格式如下
N M
X1 X2 … XM

3≤N≤2×10^5
2≤M≤2×10^5
1≤X^k ≤N
X_k !=X_k+1 (1≤k≤M−1)

-所有输入值均为整数。

【输出格式】

将答案打印为整数。

【样例输入】

样例一、

3 3
1 3 2

样例二、

4 5
2 4 2 4 2

【样例输出】

样例一、

2

样例二、

8

【样例说明】

对于第一个测试用例,
Atcoder ABC338 D - Island Tour_第1张图片

对于第二个测试用例,同一个岛可能在X1​ ,X2 ,…,XM 中出现多次。

【解题思路】

老汉使用到的是IMOS的解题方式

本题是求停掉一座桥时,最短旅程。
先停掉0号桥,也就是1岛到n岛的桥,获取本次最短旅程(可以理解为岛屿号数最小的旅游岛左边的桥),发现只有当下一个旅游点与上一旅游点的桥停掉时,数值才会发生变化,获取本次旅程,接下来依次求取,获得最小值

主要思路来源于:点击此处跳转至题解

代码注释有详细过程

【代码】

package ABC338_D_IslandTour;

import java.util.Scanner;
import java.util.Vector;

public class Main {
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		int n = scan.nextInt();
		int m = scan.nextInt();
		// 用于存放对应岛屿数据
		Vector<Integer>[] arr = new Vector[200001];
		for (int i = 0; i < 200001; i++) {
			arr[i] = new Vector<Integer>();
		}
		int[] x = new int[m];
		// 保存每个断点选择的最短旅程
		long ans = 0;
		// 获取断点设置在1岛到n岛之间的桥,也就是0桥时,最短旅程
		for (int i = 0; i < m; i++) {
			x[i] = scan.nextInt();
			// 保存好该岛次序
			arr[x[i]].add(i);
			if (i != 0) {
				// 取断点后,最短旅程只有两地之间的距离
				ans += Math.abs(x[i] - x[i - 1]);
			}
		}
		// 存放几次数据的最小值
		long res = ans;
		// 断点取到n-1即可,此时最右边的点在最左边,已经是最后一个可能答案
		for (int i = 1; i <= n - 1; i++) {
			// 获取所有旅游地次序,以免发生重复旅游时漏掉
			for (int t = 0; t < arr[i].size(); t++) {
				// 获取次序
				int j = arr[i].get(t);
				// 改变更改断点后上一岛到当前岛的旅程变化
				if (j >= 1) {
					int k = (x[j - 1] - i + n) % n;
					ans += Math.abs(n - k) - k;
				}
				// 改变更改断点后当前岛到下一岛的旅程变化
				if (j < m - 1) {
					int k = (x[j + 1] - i + n) % n;
					ans += Math.abs(n - k) - k;
				}
			}
			// 获取最小旅程
			res = Math.min(ans, res);
		}
		System.out.println(res);
		scan.close();
	}
}

你可能感兴趣的:(Java算法题解,算法,java)