-------------------------------------
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
-------------------------------------
求助,螺旋数字排列
大家看到上面虚框内的数字排列
是个5×5的数列
问题是:它的排列规律是顺时针递增
开始:左上角的1
结束:中心的25
冥思苦想,想不到设计思路
恳求高手赐教
给个设计思路即可
任何语言都行
谢谢,谢谢

解决方案 »

  1.   

    如果数组的长度已经确定的情况下.
    是不难实现.
    就跟一维数组没什么区别.
    初始化排序标志为0,已经排序了的置位为1.
    比如第一行,走到下标是4就结束,向下走.然后继续走.
    当然我的算法是比较慢的.
    也是在c中用结构体来实现的.
    不过在java中用类也行.
      

  2.   

    public class N {
       public static final int EMPTY = -1;
       public static final int LEFT = 0;
       public static final int DOWN = 1;
       public static final int RIGHT = 2;
       public static final int UP = 3;
       public static final int[][] dirs=
         new int[][]{
           {LEFT,1,0},
           {DOWN,0,1},
           {RIGHT,-1,0},
           {UP,0,-1}
       };
       
       public static int n;
       public static int[][] result;
       public static int current_direction = LEFT;
       public static int temp_dir;
       
       public static int[][] calculate(int nn){
         n = nn;
         result = new int[n][n];
         try{
            for(int i = 0; i < n; i++)
            for(int j = 0; j < n; j++)
              result[i][j]= EMPTY;
            int x = 0, y = 0;
            for(int num = 1; num <= n*n; ++num) {
               int[] xy = getNext(x,y);
               x = xy[0];y = xy[1];
               result[x][y] = num;
            }
         }catch(Exception e) {e.printStackTrace();}
          return result;
       }
       
       private static int[] getNext(int x, int y) throws Exception {
          if(result[x][y] == EMPTY)
              return new int[]{x,y};
       
          for(int num = 0; num <dirs.length; num ++) {
              int[] xy = dirs[(current_direction+num)% dirs.length];
              int xdelta = xy[1], ydelta = xy[2];
              if( (x+xdelta) >=0 && (x+xdelta) < n &&
                  (y+ydelta) >=0 && (y+ydelta) < n &&
                  result[x+xdelta][y+ydelta] == EMPTY) {
                current_direction = xy[0];
                return new int[]{x+xdelta,y+ydelta};
              }
          }
          throw new Exception("Can not find next when x="+x+" y="+y);
       }   public static void main(String[] args) {
          try{
             int[][] a = calculate(Integer.parseInt(args[0]));
             for(int y = 0; y < n; y++) {
                for(int x = 0; x < n; x++) 
                   System.out.print("\t"+a[x][y]);
                System.out.println();
             }
          }catch(Exception e){e.printStackTrace();}
       }
    }
      

  3.   

    又臭又长的来了。
    /****************************************
     * http://community.csdn.net/Expert/topic/3848/3848013.xml?temp=8.248538E-02
     *   左移:left(x+,y);
     *   右移:right(x-,y);
     *   上移:up(x,y-);
     *   下移:down(x,y+)
     *   --------------------------
     *       0 1 ...     N(x)
     *       0* * * * * * * 右 右 右 右 。 。 。 右 下
     *       1* * * * * * * 右 下
     *       .* * * * * * * 上 下
     *       .* * * * * * *   。。
     *        * * * * * * * 上 下 
     *        * * * * * * * 上 下 
     *    (y)M* * * * * * * 上 左 左 左 。 。 。 左 左 
     *   --------------------------
     *   注意坐标:(x,y) 和数组[y],[x];是反过来的,呵呵。我刚才搞错了.
     *            比如右下角的 坐标是(N,M); 数组是[M][N]
     ***************************************/
    import java.lang.String;class Point {
        private int x = 0;
        private int y = 0;
        Point(int pX, int pY) {
    setPoint(pX, pY);
        }
        public int getX() {
    return x;
        }
        public int getY() {
    return y;
        }
        public void setPoint(int pX, int pY) {
    x = pX;
    y = pY;
        }
        public Point moveBy(int mX, int mY) {
    setPoint( (x + mX),(y + mY) );
    return this;
        }
        public Point moveBy(Point moveValue) {
    //return new Point( (this.getX()+moveValue.getX()), (this.getY()+moveValue.getY()) );
    this.setPoint( (this.getX()+moveValue.getX()), (this.getY()+moveValue.getY()) );
    return this;
        }
    }class Method extends Point {
        private static int x = 0;
        private static int y = 0;
        private final int N;//x.limit;
        private final int M;//y.limit;
        private static final Point moveLeft   = new Point(-1, 0);
        private static final Point moveRight  = new Point( 1, 0);
        private static final Point moveUp     = new Point( 0,-1);
        private static final Point moveDown   = new Point( 0, 1);    Method(int pX, int pY) {
    super(0,0);
    setPoint(0,0);
    N = pX;
    M = pY;
        }
        public Point nextPoint(Point currentPoint) {
    int nIndex=-1, //当前元素所在圈(从外到内),也是下面四值的最小值+1
        gapXs=0, //与所在圈起点x的差值
        gapXe=0, //与所在圈终点x的差值
        gapYs=0, //与所在圈起点y的差值
        gapYe=0; //与所在圈终点y的差值
    boolean bLeft = false,
            bRight = false,
            bTop = false,
            bBottom = false;
    Point moveWhere = new Point(0,0); gapXs = currentPoint.getX() - 0;
    gapXe = N - currentPoint.getX();
    gapYs = currentPoint.getY() - 0;
    gapYe = M - currentPoint.getY(); do {
        bLeft   = gapXs>(nIndex+1)?false:true;
        bRight  = gapXe>(nIndex+1)?false:true;
        bTop    = gapYs>(nIndex+1)?false:true;
        bBottom = gapYe>(nIndex+1)?false:true;
        nIndex++;//从-1开始做++
    }while( !(bLeft||bRight||bTop||bBottom) ); //顺时针螺旋,判断先后为:bTop -> bRight -> bBottom -> bLeft;
    //逆时针螺旋,判断先后为:bTop <- bRight <- bBottom <- bLeft;
    if( bTop ) { //上面
        if( bRight ) //右上角,下移
    moveWhere = moveDown;
        else //上边,右移
    moveWhere = moveRight;
    }
    else if( bRight ) { //右面
        if( bBottom ) //右下角,左移
    moveWhere = moveLeft;
        else
    moveWhere = moveDown; //右边,下移
    }
    else if( bBottom ) { //下面
        if( bLeft ) //左下角:特殊
    if( (currentPoint.getY()-nIndex)==1 ) //本圈轮回结束,重新右移
        moveWhere = moveRight;
    else //左下角,上移动
        moveWhere = moveUp;
        else
    moveWhere = moveLeft; //下边,左移
    }
    else { //左面
        if( (currentPoint.getY()-nIndex)>=2 ) //左边,上移
    moveWhere = moveUp;
        else //差值为1时,表本圈轮回结束
    moveWhere = moveRight;
    }
    return currentPoint.moveBy(moveWhere); //返回currentPoint自身(已经重置),
        }
    }public class Arr {    public static void main(String [] args) { final int DEF_ARR_N = 7;
    final int DEF_ARR_M = 7;
    int arrX = 0;
    int arrY = 0; int nNumArgs = args.length;
    if( nNumArgs >=2 ) {
        arrX = Integer.parseInt(args[0]);
        arrY = Integer.parseInt(args[1]);
    }
    else {
        arrX = DEF_ARR_N;
        arrY = DEF_ARR_M;
    } int nVal    = 0;
    int [][] aa = new int[arrY][arrX];
    Point  test = new Point(0,0);
    Method meth = new Method(arrX-1,arrY-1); System.out.println("start-------------------------------------------");
    for(int i=1; i<=arrX*arrY; i++) {
    //  System.out.println("aa["+(test.getY())+"]["+(test.getX())+"]="+i);
        aa[test.getY()][test.getX()] = i;
        test = meth.nextPoint(test);
    } String printStr;
    for(int i=0; i<arrY; i++) {
        System.out.print("        ");
        for(int j=0; j<arrX; j++) {
    printStr = ("       "+aa[i][j]);
    System.out.print(   printStr.substring( (printStr.length()-7), printStr.length() )   );
        }
        System.out.println("");
    }
        }
    }
      

  4.   

    D:\MyJava>javac Arr.javaD:\MyJava>java  Arr 5 6
    start-------------------------------------------
                  1      2      3      4      5
                 18     19     20     21      6
                 17     28     29     22      7
                 16     27     30     23      8
                 15     26     25     24      9
                 14     13     12     11     10D:\MyJava>