首页 > 专题系列 > Java解POJ > POJ 3099 Go Go Gorelians [解题报告] Java
2013
11-12

POJ 3099 Go Go Gorelians [解题报告] Java

Go Go Gorelians

问题描述 :

The Gorelians travel through space using warp links. Travel through a warp link is instantaneous, but for safety reasons, an individual can only warp once every 10 hours. Also, the cost of creating a warp link increases directly with the linear distance between the link endpoints.

The Gorelians, being the dominant force in the known universe, are often bored, so they frequently conquer new regions of space in the following manner.

1) The initial invasion force finds a suitable planet and conquers it, establishing a Regional Gorelian Galactic Government, hereafter referred to as the RGGG, that will govern all Gorelian matters in this region of space.

2) When the next planet is conquered, a single warp link is constructed between the new planet and the RGGG planet. Planets connected via warp links in this manner are said to be part of the Regional Gorelian Planetary Network, that is, the RGPN.

3) As additional planets are conquered, each new planet is connected with a single warp link to the nearest planet already in the RGPN, thus keeping the cost of connecting new planets to the network to a minimum. If two or more planets are equidistant from the new planet, the new planet is connected to whichever of them was conquered first.

This causes a problem however. Since planets are conquered in a more-or-less random fashion, after a while, the RGGG will probably not be in an ideal location. Some Gorelians needing to consult with the RGGG might only have to make one or two warps, but others might require dozens—very inconvenient when one considers the 10-hour waiting period between warps.

So, once each Gorelian year, the RGGG analyzes the RGPN and relocates itself to an optimal location. The optimal location is defined as a planet that minimizes the maximum number of warps required to reach the RGGG from any planet in the RGPN. As it turns out, there is always exactly one or two such planets. When there are two, they are always directly adjacent via a warp link, and the RGGG divides itself evenly between the two planets.

Your job is to write a program that finds the optimal planets for the RGGG. For the purposes of this problem, the region of space conquered by the Gorelians is defined as a cube that ranges from (0,0,0) to (1000,1000,1000).

输入:

The input consists of a set of scenarios where the Gorelians conquer a region of space. Each scenario is independent. The first line of the scenario is an integer N that specifies the total number of planets conquered by the Gorelians. The next N lines of the input specify, in the order conquered, the IDs and coordinates of the conquered planets to be added to the RGPN, in the format ID X Y Z. An ID is an integer from 1 to 1000. X, Y, and Z are integers from 0 to 1000. A single space separates the numbers. A value of N = 0 marks the end of the input.

输出:

For each input scenario, output the IDs of the optimal planet or planets where the RGGG should relocate. For a single planet, simply output the planet ID. For two planets, output the planet IDs, smallest ID first, separated by a single space.

样例输入:

5
1 0 0 0
2 0 0 1
3 0 0 2
4 0 0 3
5 0 0 4
5
1 0 0 0
2 1 1 0
3 3 2 0
4 2 1 0
5 3 0 0
10
21 71 76 4
97 32 5 69
70 33 19 35
3 79 81 8
31 91 17 67
52 31 48 75
48 90 14 4
41 73 2 21
83 74 41 69
26 32 30 24
0

样例输出:

3
2 4
31 97

解题代码:

//* @author: SmilingWang
import java.util.*;
public class Main {

 public static void main(String[] args) {
   int n;
   Scanner in = new Scanner(System.in);
		
   while(true){
     n = in.nextInt();
     Planet[] d = new Planet[n+1];
     if(n == 0){
	return;
     }
     for(int i = 1; i <= n; i++){
	int id = in.nextInt();
	int x = in.nextInt();
	int y = in.nextInt();
	int z = in.nextInt();
	d[i] = new Planet(id, x, y, z);
     }
     f(n, d);
   }
  }
	
  public static void f(int n, Planet[] d){
    int[][] con = new int[n+1][n+1];
    for(int i = 1; i <= n; i++){
	con[i][i] = 0;
    }
    for(int i = 2; i <= n; i++){
	int min = Integer.MAX_VALUE;
	int mid = 1;
	//display(n, con);
	//System.out.println();
	for(int j = 1; j < i; j++){
	   int dis = dis(d[i], d[j]);
	   //System.out.println(dis + " " + i + " " + j);
	   if(dis < min){
		min = dis;
		mid = j;
	   }
	}
	con[i][mid] = 1;
	con[mid][i] = 1;
	for(int j = 1; j < i; j++){
	   if(j == mid){
		continue;
	   }
	   con[i][j] = con[mid][j] + 1;
	   con[j][i] = con[i][j];
	}
	//display(n, con);
	//System.out.println();
     }
	
     int max[] = new int[n+1];
     for(int i = 1; i <= n; i++){
	for(int j = 1; j <= n; j++){
	  if(con[i][j] > max[i]){
	    max[i] = con[i][j];
	   }
	}
     }
     int min = Integer.MAX_VALUE;
     int min2 = Integer.MAX_VALUE;
     int mid = 1;
     int mid2 = 1;
     for(int i = 1; i <= n; i++){
	if(max[i] < min){
	  min = max[i];
	  mid = i;
	 }
      }
      for(int i = 1; i <= n; i++){
	 if(i == mid){
	   continue;
	  }
     if(max[i] < min2){
	min2 = max[i];
	mid2 = i;
      }
     }
    if(min != min2){
	System.out.println(d[mid].id);
    }
    else{
	if(d[mid].id > d[mid2].id){
		int temp = d[mid2].id;
		d[mid2].id = d[mid].id;
		d[mid].id = temp;
	}
	System.out.println(d[mid].id + " " + d[mid2].id);
     }
   }

   public static int dis(Planet d1, Planet d2){
	return (int)(Math.pow(d1.x - d2.x, 2) + Math.pow(d1.y-d2.y, 2) + Math.pow(d1.z-d2.z, 2));
   }

   public static void display(int n, int d[][]){
	for(int i = 1; i <= n; i++){
         for(int j = 1; j <= n; j++){
		System.out.print(d[i][j] + " ");
	   }
	   System.out.println(" ");
	 }
    }
}

class Planet{
	int id;
	int x;
	int y;
	int z;
	
	public Planet(int id, int x, int y, int z){
		this.id = id;
		this.x = x;
		this.y = y;
		this.z = z;
	}
}

  1. 算法是程序的灵魂,算法分简单和复杂,如果不搞大数据类,程序员了解一下简单点的算法也是可以的,但是会算法的一定要会编程才行,程序员不一定要会算法,利于自己项目需要的可以简单了解。

  2. 思路二可以用一个长度为k的队列来实现,入队后判断下队尾元素的next指针是否为空,若为空,则出队指针即为所求。

  3. 第一句可以忽略不计了吧。从第二句开始分析,说明这个花色下的所有牌都会在其它里面出现,那么还剩下♠️和♦️。第三句,可以排除2和7,因为在两种花色里有。现在是第四句,因为♠️还剩下多个,只有是♦️B才能知道答案。