基本上我的问题是:给定一个数字n表示方形网格的宽度和高度,我需要找到一个凸出的90度旋转对称多边形的点,其中最大边数适合网格,其中点只能在网格的格点上进行,并且边必须从一个点直接到另一个点。我对它的尝试导致总共2516个边,n = 100000,但是我被认为它应该有7592.我使用的函数在下面,问题描述本身是here。< / p>
static Point[] getPoints(final int n) {
// first, figure out the max number of sides
int sides = 0; boolean jump = false;
for(int inc = 2, max = 0; max < n; jump = !jump, sides += 4)
max += (jump) ? ++inc : inc;
// next, compute the point translations
Point[] pts = new Point[sides];
Point[] translations = new Point[sides];
translations[0] = new Point(0,1); jump = true;
// systematically generate translations used
for(int i = 1, j = 1; i < sides/4; i++, jump = !jump)
translations[i] = (jump) ? new Point(1, j++) : new Point(j, 1);
// sort the first 4th into correct translation order
Arrays.sort(translations, new Comparator<Point>() {
public int compare(Point a, Point b) {
if(a == null || b == null) return 0;
return a.x < b.x ? -1 : a.x == b.x ?
a.y > b.y ? -1 : a.y == b.y ? 0 : 1 : 1;
}
});
// use first 4th to generate the rest
for(int i = translations.length/4; i < translations.length; i++)
translations[i] = new Point(translations[i-(translations.length/4)].y,
-translations[i-(translations.length/4)].x);
// finally, find first point and use translations to generate the rest
int y = 0; jump = true;
for(int i = 0, j = 1; i < sides; i += 4, jump = !jump)
y += (jump) ? j++ : 1;
pts[0] = new Point(0, y);
for(int i = 1; i < pts.length; i++) {
pts[i] = new Point(pts[i-1]);
pts[i].translate(translations[i].x, translations[i].y);
}
// now reverse x's and y's
for(int i = 0; i < pts.length; i++)
pts[i] = new Point(pts[i].y, pts[i].x);
// and then put last point in front
Point first = pts[pts.length-1];
for(int i = pts.length-1; i > 0; i--)
pts[i] = pts[i-1];
pts[0] = first;
// and then adjust points to make the wheel symmetrical around the n-block
int w = 0, h = 0;
for(int i = 1; i < sides/4; i++) {
h += translations[i].x;
w += translations[i].y;
}
int adj = n - (w+h+1);
for(int i = 1; i <= sides/4; i++) pts[i].translate(adj, 0);
for(int i = (sides/4)+1; i <= sides/2; i++) pts[i].translate(adj, adj);
for(int i = (sides/2)+1; i <= 3*(sides/4); i++) pts[i].translate(0, adj);
return pts;
}