螺旋队列

螺旋队列的样子如下图:

两大规律:

1、螺旋规律

2、奇数(圈数,或X轴正坐标)平方规律(紫线)

问题描述:

设1的坐标是(0,0),x方向向右为正,y方向向下为正,例如,7的坐标为(-1,-1),2的坐标为(1,0)。编程实现输入任意一点坐标(x,y),输出所对应的数字!

问题解决:

从紫线突破。

从图中不难发现,每圈最大值max=(2*c+1)(2*c+1),c为由内往外的圈数,c>=0。如图每圈最大值分别是1、9、25、49、81........,算出每圈的max后,就分4条边分别计算每圈的其他值。通过坐标落在该圈4条边的哪条边上,按照不同的公式计算出具体坐标点的值。

以第3圈(max=49)为例,4条边划分如下图(以颜色区分):

这里先给出4条边上各坐标上的值与max的对应关系为:

上边:Utop = max+(x+y);

左边: Uleft= max+(3*x-y);

下边:Ubottom = max + (-x - 5*y);

右边:Uright = max+(-7*x+y);

那么这些关系是怎么得出来的呢?再看图中画上圈的数字(将其值表示为topBase,xxBase),我们称其为每条边的基准值:

在上边,y坐标不变,x坐标变化步长为1。令x=0,此时,topBase=max+y作为该边的基准值,其他值随x的变化而变化,得在该区域u=max+y+x;

同理,在左边,x坐标不变,y坐标变化步长为1。令y=0,此时,u=max+3*x作为该边的基准值,其他值随y的变化而变化,得在该区域u=vc+3*x-y;

同理得其他俩区域的表达式。不再赘述。

 观察这些基准值与max值之间关系,不难发现,这些基准值与max之间的差分别是1C(上边),3C(左边),5C(下边),7C(右边)(C表示当前圈数),在上边和下边,y坐标表示(或等于)圈数(即C=y),而在左边和右边,x坐标表示(或等于)圈数(即C=x)。因此前面提到的差值又可用坐标表示成1y,3x,5y,7x。因此就产生了各边基准值的计算公式:

topBase=max+y

leftBase=max+3x

bottomBase=max-5y

rightBase=max-7x

(注意坐标的符号,负数加,正数减,因为基准值肯定都比max要小)

下面得出每条边的值,首先考虑上边和下边,这2条边,在基准值的基础上,由x坐标控制增减,因此:

topValue=topBase+x=max+y+x(上边,随x赠而赠,因此是加x)

bottomValue=bottomBase-x=max-5y-x(下边,随x赠而减,因此是减x)

同理,左边和右边,则在基准值的基础上,由y坐标控制增减,因此:

leftValue=leftBase-y=max+3x-y(左边,随y赠而减,因此是减y)

rightValue=rightBase+y=max-7x+y(右边,随y赠而赠,因此是加y)

 程序实现

 
  1. /**

  2. * 打印螺旋数列

  3. *

  4. * @author nathan

  5. *

  6. */

  7. public class SpiralSeq {

  8. public static void main(String[] args) {

  9. for (int y = -5; y <= 5; ++y) {

  10. for (int x = -5; x <= 5; ++x) {

  11. System.out.printf("%5d", spiral(x, y));

  12. }

  13. System.out.println();

  14. }

  15. }

  16.  
  17. private static Object spiral(int x, int y) {

  18. int c = max(abs(x), abs(y));// 当前坐标所在圈

  19. int max = (c * 2 + 1) * (c * 2 + 1);// 当前圈上最大值

  20.  
  21. if (y == -c) { // 上边

  22. return max + (x + y);

  23. } else if (x == -c) {// 左边

  24. return max + (3 * x - y);

  25. } else if (y == c) {// 下边

  26. return max + (-x - 5 * y);

  27. } else {// 右边

  28. return max + (-7 * x + y);

  29. }

  30. }

  31.  
  32. private static int max(int n1, int n2) {

  33. return n1 > n2 ? n1 : n2;

  34. }

  35.  
  36. private static int abs(int x) {

  37. return x > 0 ? x : -x;

  38. }

  39. }


Output:

 
  1. 111 112 113 114 115 116 117 118 119 120 121

  2. 110 73 74 75 76 77 78 79 80 81 82

  3. 109 72 43 44 45 46 47 48 49 50 83

  4. 108 71 42 21 22 23 24 25 26 51 84

  5. 107 70 41 20 7 8 9 10 27 52 85

  6. 106 69 40 19 6 1 2 11 28 53 86

  7. 105 68 39 18 5 4 3 12 29 54 87

  8. 104 67 38 17 16 15 14 13 30 55 88

  9. 103 66 37 36 35 34 33 32 31 56 89

  10. 102 65 64 63 62 61 60 59 58 57 90

  11. 101 100 99 98 97 96 95 94 93 92 91

--------------------- 本文来自 塘外人 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/yhmhappy2006/article/details/2934435?utm_source=copy

猜你喜欢

转载自blog.csdn.net/H7123SY/article/details/82956506