import java.io.*; import java.util.*; import java.awt.geom.*; /** * Solution to Hilbert Sort * * @author vanb */ public class hilbert_vanb { public Scanner sc; public PrintStream ps; /** * A sortable point. * * @author vanb */ public class Location implements Comparable { /** Coordinates of the point */ public int x, y; /** A key to sort on, and a label to print */ public String key, label; /** * Create a Location. * * @param x X coordinate * @param y Y coordinate * @param label Label for printing * @param key Key for sorting */ public Location( int x, int y, String label, String key ) { this.x = x; this.y = y; this.label = label; this.key = key; } @Override /** * Compare two Locations by key. * * @param loc Another Location * @return Standard for compareTo */ public int compareTo( Location loc ) { return key.compareTo( loc.key ); } /** * A String for printing. * * @return A String for printing. */ public String toString() { return label; } } /** * Make a Key for sorting a Location. * * This is the key to the problem. Let's start by numbering the quadrants: * * 2 | 3 * --+-- * 1 | 4 * * The curve is complicated - but observe that every point in Q1 comes before * every point in Q2, which comes before every point in Q3, then Q4. So, just see * which quadrant a point is in. Give all points in Q1 an 'a', Q2 a 'b', * Q3 is 'c' and Q4 is 'd'. * * What if more than one point is in the same quadrant? * Well, then, just split that quadrant up into quadrants and pull the same trick. * Append their letter to the end of the key. You can keep going until * all points have their own unique key. * * It's not *quite* that simple. You have to do some translating, rotating, flipping and scaling, * and it's different depending on which quadrant you're in. * * @param x X coordinate * @param y Y coordinate * @param s The size of the square * @param level Recursion depth * @return A Key for sorting. */ public String makekey( double x, double y, double s, int level ) { String key = ""; if( level>0 ) { --level; double s2 = s/2.0; // Q1: the subquadrants look like this: // 4 | 3 // --+-- // 1 | 2 // So, we've go to flip around the 1-3 diagonal if( x<=s2 && y<=s2 ) key = "a" + makekey( y, x, s2, level ); // Q2: The orientation stays the same, but y has to be translated. else if( x<=s2 && y>s2 ) key = "b" + makekey( x, y-s2, s2, level ); // Q3: Like Q2, but both x and y have to be translated else if( x>s2 && y>s2 ) key = "c" + makekey( x-s2, y-s2, s2, level ); // Q4 is the most complicated, so it's left as an exercise for the reader. else if( x>s2 && y<=s2 ) key = "d" + makekey( s2-y, s-x, s2, level ); } return key; } /** * Driver. * @throws Exception */ public void doit() throws Exception { sc = new Scanner( System.in ); ps = System.out; int n = sc.nextInt(); double s = sc.nextDouble(); Location locs[] = new Location[n]; for( int i=0; i