查找具有最大边的多边形

时间:2012-09-26 02:53:59

标签: java algorithm

基本上我的问题是:给定一个数字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;
    }

0 个答案:

没有答案