After solving the problem, I heard that I could get an Amazon gift certificate or meat by lottery, so I tried it. https://paiza.jp/poh/phantom_thief
The treasure location information is written with the x, y coordinates of N treasures in meters, with the location of the phantom thief as 0, 0. It moves in a straight line between each coordinate. Start from the 0,0 position and output the route that steals all the treasure with the shortest possible route.
If you output the coordinates closest to the origin, output the coordinates closest to that coordinate again, and so on, you can proceed with a short route. I thought, I tried to solve it.
It was written that the answer could be written on a blog, so I posted it below.
Submission code
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String firstLine = sc.nextLine().replaceAll(" ","");
int itemCount = Integer.parseInt(firstLine);
ArrayList<Point> pointList = new ArrayList<Point>();
//Create a coordinate list from standard input
for(int i = 0; i < itemCount ; i++){
String[] line = sc.nextLine().split(" ");
int x = Integer.parseInt(line[0]);
int y = Integer.parseInt(line[1]);
pointList.add(new Point(x,y));
}
Point originPoint = new Point(0,0);
while(pointList.size() > 0){
int minDistance = Integer.MAX_VALUE;
Point minDistancePoint = new Point();
//Get the coordinates closest to the reference point from the coordinate list
for(Point getPoint : pointList){
int tmpDistance = getDistance(originPoint,getPoint);
if(minDistance > tmpDistance){
minDistance = tmpDistance;
minDistancePoint = getPoint;
}
}
//Display coordinate position
minDistancePoint.output();
//Change the reference point
originPoint = minDistancePoint;
//Remove coordinates from the coordinate list
int index = pointList.indexOf(minDistancePoint);
pointList.remove(index);
}
}
//Find the distance between the coordinates of two points
public static int getDistance(Point p1, Point p2) {
double x1 = p1.x;
double y1 = p1.y;
double x2 = p2.x;
double y2 = p2.y;
double distance = Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
return (int) distance;
}
}
//Coordinate class
class Point{
int x;
int y;
public Point(){
this.x = 0;
this.y = 0;
}
public Point(int x , int y){
this.x = x;
this.y = y;
}
public void output(){
System.out.println(x + " " + y);
}
}
Here. It seems that it was not the optimal solution. https://paiza.jp/poh/phantom_thief/result/a8a222d8
After a little research, [Traveling Salesman Problem](https://ja.wikipedia.org/wiki/%E5%B7%A1%E5%9B%9E%E3%82%BB%E3%83%BC%E3 It seems to be a problem called% 83% AB% E3% 82% B9% E3% 83% 9E% E3% 83% B3% E5% 95% 8F% E9% A1% 8C). (Is it a little different because you don't have to go back to the first coordinates?)
The method I solved this time seems to be an algorithm called "greedy method".
Algorithms for solving the traveling salesman problem include the "2-opt method", "hill climbing method", and "simulated annealing method". Using these methods seems to be closer to the optimal solution, but I gave up because it seems difficult.
Recommended Posts