蛇形数组

若涉及侵权,请联系,马上会删除,初次发帖,若有得罪多多见谅。

若涉及侵权,请联系,马上会删除,初次发帖,若有得罪多多见谅。

若涉及侵权,请联系,马上会删除,初次发帖,若有得罪多多见谅。

题:输出如下数组:

1 2 4

12 13 14 5

11 16 15 6

10 9 7


解题思路:
1、定义二维数组snack[n][n]
2、定义一个初始数值,用于累加和,计算遍历时,当下位置的数值。num = 1
定义坐标x,y(x=0,y=0)用于判断当前位置
3、循环条件,while(num<n^2)
4、第一次转向:向右转向 判断是否超出边界值,以及下一个数字是否为0 ,满足条件,填入数字,位置前移
while(y+1<snack[x].length()&&snack[x][y+1]==0){
y++;
snack[x][y] = ++num;
}
第二次转向:向下转向 判断边界及其下一个值,满足条件,填入数字,位置下移

while (x + 1 < snack.length && snack[x + 1][y] == 0) {
x++;
snack[x][y] = ++num;

}

第三次,第四次 分别向上向左

难点:转向判定条件,初始值设定。

实现代码:
public class Snake {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[][] snake = new int[4][4];
		int x = 0, y = 0;
		int num = 1;
		snack[0][0] = 1;// 蛇头

		while (num < 15) {

			while (y + 1 < snack[x].length && snake[x][y + 1] == 0) {
				y++;
				snack[x][y] = ++num;
			} // 向右 1 2 3 4

			while (x + 1 < snack.length && snake[x + 1][y] == 0) {
				x++;
				snack[x][y] = ++num;

			} // 向下

			while (y - 1 >= 0 && snake[x][y - 1] == 0) {
				y--;
				snack[x][y] = ++num;
			} // 向左

			while (x - 1 >= 0 && snake[x - 1][y] == 0) {
				x--;
				snack[x][y] = ++num;
			} // 向上

		}
		for (int[] ele : snake) {
			for (int j : ele) {
				System.out.print(j + "\t");
			}
			System.out.println();
		}
	}

这样的写法虽然简单,但也是参照了 http://www.cnblogs.com/kaima/p/4773908.html的帖子(写了一个多小时)

重点来了,这样还是不能满足某位dalao对我的期待值,应该优化一下代码。Orz心好累啊。


继承上面的思想,转弯可以看成是XdirArr和YdirArr两个数组组成的集合,转弯的方向是恒定四个方向,即:
int []XdirArr={0,1,0,-1};
int []YdirArr={1,0,-1,0};

简化转向判断条件:
转向判断条件离不开两个点:
1、超过边界范围
(y+YdirArr[i])>(Snake[x].length()-1)
当 YdirArr[i]==1 向右时 超过了数组的长度

(y+YdirArr[i])<0

当 YdirArr[i]==-1 向左时 小于数组长度

(x+XdirArr[i])>(Snake.length()-1)

当XdirArr[i]==1 向下时 超过了数组的长度

向上时 不可能超过边界 可以自行理解

2、下一个位置有数字了

相对应下一个位置就是:
snack[x+XdirArr[i]][y + YdirArr[i]]

可以得到结论:
snack[x+XdirArr[i]][y + YdirArr[i]]!=0

3、以上连点必须全部满足,若有一点不满足,那么就转向即i++

最终结论:

if((y+YdirArr[i])>(N-1)||(y+YdirArr[i])<0||(x+XdirArr[i])>(N-1)||snake[x+XdirArr[i]][y+YdirArr[i]]!=0){
i++;
if(i%4 ==0) i = 0;//因为要转圈圈,所以方向必须循环取
}

判断是否转向以后,进行数组的赋值
y = y+YdirArr[i];
x = x+XdirArr[i];
snake[x][y] = ++num;





实现代码:
public class Snake {
	final static int N = 8;
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		int [][] snake = new int [N][N];
		int num = 1;
		int i = 0;
		int x = 0,y = 0;
		snake[0][0] = 1;
		int []XdirArr={0,1,0,-1};
		int []YdirArr={1,0,-1,0};
		while(num  < N*N){
			
			if((y+YdirArr[i])>(N-1)||(y+YdirArr[i])<0||(x+XdirArr[i])>(N-1)||snake[x+XdirArr[i]][y+YdirArr[i]]!=0){				
				i++;
				if(i%4 ==0) i = 0;
			}
			y = y+YdirArr[i];
			x = x+XdirArr[i]; 
			snake[x][y] = ++num;
			
		
			
		}
		for(int[] ele:snake){
			for(int ele1:ele){
				System.out.print(ele1+"\t");
			}
			System.out.println();
		}
	}

}

emmmmmm,大佬说还可以优化,翻转坐标,今天晚上再更吧。。吃饭去



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值