-------------------------------------
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 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
冥思苦想,想不到设计思路
恳求高手赐教
给个设计思路即可
任何语言都行
谢谢,谢谢
是不难实现.
就跟一维数组没什么区别.
初始化排序标志为0,已经排序了的置位为1.
比如第一行,走到下标是4就结束,向下走.然后继续走.
当然我的算法是比较慢的.
也是在c中用结构体来实现的.
不过在java中用类也行.
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();}
}
}
/****************************************
* 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("");
}
}
}
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>