[Vicious--算法] 骑士聚会(《程序员》的算法擂台)
leon_a
2007-09-06
64的性能也不会差,这个算法的复杂度本身就不高,呵呵,他们给的数据规模较小,所以暴力法也算一个选择,期待更优算法,我计算几何比较差劲,搞不了深入的数学问题
|
|
xufei0110
2007-09-06
中午想了一下,没时间写程序(这个破公司就跟监狱似的 什么也不让干)
1, 求出每个骑士能走到的点的坐标集 P[n][x][y]=[]; 2, 求出这些坐标集的交集,就是这些骑士可能聚会的地点坐标集 3, 求出这个聚会点坐标集里的每个点 所有骑士用的时间总和集 4, 找出这个时间集里的最小值 |
|
leon_a
2007-09-06
snowind9 写道 算法就是为了让自己不麻木。做对日做久了就麻木了。
嗯,做些copy的活无聊,就用恶心的算法折磨自己 |
|
leon_a
2007-09-08
进行了优化,牺牲空间来优化时间 64个骑士的运行时间在125ms
package convex; public class Point { public int x, y; public Point(int x, int y) { if (x > 7 || y > 7) { throw new RuntimeException("out of matrix"); } this.x = x; this.y = y; } public String toString() { return "x=" + x + ",y=" + y; } } 算法类 package convex; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.StringTokenizer; import convex.Point; public class Algo { private boolean[][] flg = new boolean[8][8]; private int[][] shortPath = new int[8][8]; //最短距离矩阵 public int[][] distanceSq(Point p1) { djkst(p1); return shortPath; } //仿迪杰科斯特最短路径 private void djkst(Point p1) { Point[] queue = new Point[64]; flg[p1.x][p1.y] = true; queue[0] = p1; int j=0; int queueSize = 1; while (j < queue.length) { Point temp = queue[j]; Point[] list = getList(temp); for(int i=0;i < list.length;i++) { if(list[i] != null) { Point w = list[i]; if (!flg[w.x][w.y]) { shortPath[w.x][w.y] = shortPath[temp.x][temp.y] + 1; queue[queueSize++] = w; flg[w.x][w.y] = true; } } } j++; } } //可行步数集 private static Point[] getList(Point point) { Point[] list = new Point[8]; int length = 0; if (point.x + 2 <= 7 && point.y + 1 <= 7) { list[length++] = new Point(point.x + 2, point.y + 1); } if (point.x - 2 >= 0 && point.y - 1 >= 0) { list[length++] = new Point(point.x - 2, point.y - 1); } if (point.x + 1 <= 7 && point.y + 2 <= 7) { list[length++] = new Point(point.x + 1, point.y + 2); } if (point.x - 1 >= 0 && point.y - 2 >= 0) { list[length++] = new Point(point.x - 1, point.y - 2); } if (point.x + 2 <= 7 && point.y - 1 >= 0) { list[length++] = new Point(point.x + 2, point.y - 1); } if (point.x - 2 >= 0 && point.y + 1 <= 7) { list[length++] = new Point(point.x - 2, point.y + 1); } if (point.x + 1 <= 7 && point.y - 2 >= 0) { list[length++] = new Point(point.x + 1, point.y - 2); } if (point.x - 1 >= 0 && point.y + 2 <= 7) { list[length++] = new Point(point.x - 1, point.y + 2); } return list; } public static int[] method(Point[] points, int i,int j,Object[] pointList) { int maxDay = 0; int distance = 0; for(int k=0;k<pointList.length;k++) { int day = ((int[][])pointList[k])[i][j]; distance += day; if(maxDay<day) { maxDay = day; } } return new int[]{maxDay,distance}; } public static void main(String[] args) throws IOException { //数据输入 //数据输入格式:第一个数字是骑士n,第2,3个数字是第一个骑士的坐标,依次类推。 //每个数字之间以空格区分 BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in)); String line = stdin.readLine(); StringTokenizer st = new StringTokenizer(line); int pointLength = Integer.parseInt(st.nextToken()); Point[] points = new Point[pointLength]; for(int i=0;i<points.length;i++) { int x = Integer.parseInt(st.nextToken()); int y = Integer.parseInt(st.nextToken()); points[i] = new Point(x,y); } Object[] pointList = new Object[points.length]; for (int j = 0; j < points.length; j++) { pointList[j] = new Algo().distanceSq(points[j]); } int minDay = 999999999; int minDistance = 999999999; int x = 0; int y = 0; for(int i=0;i<7;i++) { for(int j=0;j<7;j++) { int[] result = Algo.method(points, i,j,pointList); //找最短天数,最短天数相同,找最短距离 if (minDay > result[0]) { minDay = result[0]; minDistance = result[1]; x = i; y = j; } else if(minDay == result[0]) { if(minDistance > result[1]) { minDistance = result[1]; x = i; y = j; } } } } //数据输出x,y点坐标,最小天数 System.out.println("" + x+" "+y+" "+minDay); } } |
|
leon_a
2007-09-10
仔细想了一下,这个输出应该不只有一个点所以程序修改如下
package convex; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.StringTokenizer; import convex.Point; public class Algo { private boolean[][] flg = new boolean[8][8]; private int[][] shortPath = new int[8][8]; //最短距离矩阵 public int[][] distanceSq(Point p1) { djkst(p1); return shortPath; } //仿迪杰科斯特最短路径 private void djkst(Point p1) { Point[] queue = new Point[64]; flg[p1.x][p1.y] = true; queue[0] = p1; int j=0; int queueSize = 1; while (j < queue.length) { Point temp = queue[j]; Point[] list = getList(temp); for(int i=0;i < list.length;i++) { if(list[i] != null) { Point w = list[i]; if (!flg[w.x][w.y]) { shortPath[w.x][w.y] = shortPath[temp.x][temp.y] + 1; queue[queueSize++] = w; flg[w.x][w.y] = true; } } } j++; } } //可行步数集 private static Point[] getList(Point point) { Point[] list = new Point[8]; int length = 0; if (point.x + 2 <= 7 && point.y + 1 <= 7) { list[length++] = new Point(point.x + 2, point.y + 1); } if (point.x - 2 >= 0 && point.y - 1 >= 0) { list[length++] = new Point(point.x - 2, point.y - 1); } if (point.x + 1 <= 7 && point.y + 2 <= 7) { list[length++] = new Point(point.x + 1, point.y + 2); } if (point.x - 1 >= 0 && point.y - 2 >= 0) { list[length++] = new Point(point.x - 1, point.y - 2); } if (point.x + 2 <= 7 && point.y - 1 >= 0) { list[length++] = new Point(point.x + 2, point.y - 1); } if (point.x - 2 >= 0 && point.y + 1 <= 7) { list[length++] = new Point(point.x - 2, point.y + 1); } if (point.x + 1 <= 7 && point.y - 2 >= 0) { list[length++] = new Point(point.x + 1, point.y - 2); } if (point.x - 1 >= 0 && point.y + 2 <= 7) { list[length++] = new Point(point.x - 1, point.y + 2); } return list; } public static int[] method(Point[] points, int i,int j,Object[] pointList) { int maxDay = 0; int distance = 0; for(int k=0;k<pointList.length;k++) { int day = ((int[][])pointList[k])[i][j]; distance += day; if(maxDay<day) { maxDay = day; } } return new int[]{maxDay,distance}; } public static void main(String[] args) throws IOException { //数据输入 //数据输入格式:第一个数字是骑士n,第2,3个数字是第一个骑士的坐标,依次类推。 //每个数字之间以空格区分 BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in)); String line = stdin.readLine(); StringTokenizer st = new StringTokenizer(line); int pointLength = Integer.parseInt(st.nextToken()); Point[] points = new Point[pointLength]; for(int i=0;i<points.length;i++) { int x = Integer.parseInt(st.nextToken()); int y = Integer.parseInt(st.nextToken()); points[i] = new Point(x,y); } Object[] pointList = new Object[points.length]; for (int j = 0; j < points.length; j++) { pointList[j] = new Algo().distanceSq(points[j]); } int minDay = 999999999; int minDistance = 999999999; for(int i=0;i<7;i++) { for(int j=0;j<7;j++) { int[] result = Algo.method(points, i,j,pointList); //找最短天数,最短天数相同,找最短距离 if (minDay > result[0]) { minDay = result[0]; minDistance = result[1]; } else if(minDay == result[0]) { if(minDistance > result[1]) { minDistance = result[1]; } } } } for(int i=0;i<7;i++) { for(int j=0;j<7;j++) { int[] result = Algo.method(points, i,j,pointList); if(minDay == result[0] && minDistance == result[1]) { System.out.println(i+" " + j +" "+ minDay); } } } } } |
|
renshengjihe
2007-09-10
我怎么感觉我离计算机越来越远了啊.
|
|
leon_a
2007-09-20
都是咱们大学学的数据结构,还有大四老师给讲的算法里的
|