螺旋队列

螺旋队列算法分析

6664人阅读 评论(19) 收藏 举报

 

螺旋队列的样子如下图:

 

 

 

两大规律:

1。螺旋规律(红线)

2。奇数平方规律(紫线)

 

问题描述:

 

设1的坐标是(0,0),的方向向右为正,y方向向下为正,例如,7的坐标为(-1,-1),

2的坐标为(0,1)。编程实现输入任意一点坐标(x,y),输出所对应的数字!

 

 

问题解决:

从紫线突破。从图中不难发现,右上角vc=(2*t+1)(2*t+1),t为该圈x,y坐标的绝对值的最大值。例如vc=9、25、49、81........,算出vc后,就分4个判断区域,分别判断,点落在该圈4条边的哪条边上,从而计算出具体坐标点的值。

四个区域划分如下图:

 

 

4个区域内4条边上的值u与vc的对应关系为:

y=-t区:u = vc+(x+y);

x=-t区:u = vc+(3*x-y);

y=t区:u = vc + (-x - 5*y);

x=t区:u = vc+(-7*x+y);

 

那么这些关系是怎么得出来的呢?再看图中画上圈的数字:

 

 

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

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

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

 

 

程序实现:

  1. #include <iostream>
  2. #include <string>

  3. using namespace std;
  4. #define abs(a)    ((a)>0?(a):(-a))
  5. #define max(a,b) ((a)>(b)?(a):(b))


  6. int spiralval(int x,int y)
  7. {
  8. int t = max(abs(x),abs(y));
  9. int vc = (t*2+1)*(t*2+1);
  10. int u;

  11. if ( y == -t) //分别判断,点落在该圈4条边的哪条边上
  12.      u = vc+(x+y);
  13. else if (x == -t)
  14.     u = vc+(3*x-y);
  15. else if (y == t)
  16.      u = vc + (-x - 5*y);
  17. else
  18.      u = vc+(-7*x+y);

  19. return u;
  20. }


  21. int main()
  22. {

  23. int x,y;

  24. cout << endl;

  25. for(y=-5;y<=5;y++)
  26.     {
  27.       for(x=-5;x<=5;x++)
  28.     printf("%5d",spiralval(x,y));
  29.       
  30.       printf("/n");

  31.     }
  32. cin.get();
  33. return 0;
  34. }


一种螺旋队列的描述:

 

21   22   23   24   。。

20   7     8     9     10

19   6     1     2     11

18   5     4     3     12

17   16   15   14   13

 

     这是一个顺时针的螺旋数列,设1的坐标是(0,0),取x的正方向为向右,取y的正方向为向下。则7的坐标就是(-1,-1),2的坐标是(0,1),3的坐标是(1,1)。

 

现在需要编程实现:

1,输入一个坐标输出对应的数字;

2,输入一个数字输出对应的坐标。

 

代码如下:

  1. #include <stdio.h>  
  2. int step=0;  
  3. int key=1;  
  4. int N=0;  
  5. typedef struct  
  6. {  
  7.     int x;  
  8.     int y;  
  9. }node;  
  10. node A[100];  
  11. int temp_x=0,temp_y=0;  
  12. int x,y=0;  
  13. bool Isexsit();  
  14. bool Isaim();  
  15. int main()  
  16. {  
  17.     printf("1.输入坐标->输出对应的数(默认)/n2.输入数字->输出对应的坐标/n");  
  18. input:  
  19.     printf("请选择模式:");  
  20.     scanf("%d",&key);  
  21.     if(key==1)  
  22.     {  
  23.         printf("输入坐标值:");  
  24.         scanf("%d%d",&x,&y);  
  25.     }  
  26.     else if(key==2)  
  27.     {  
  28.         printf("输入数字:");  
  29.         scanf("%d",&N);  
  30.     }  
  31.     else  
  32.     {  
  33.         printf("Error Operation/n");  
  34.         goto input;  
  35.     }  
  36.     while(1)  
  37.     {  
  38. operation1:  
  39.         temp_x++;step++;  
  40.         if(!Isexsit())  
  41.         {  
  42.             A[step].x=temp_x;  
  43.             A[step].y=temp_y;  
  44.             if(Isaim())  
  45.                 break;  
  46.         }  
  47.         else if(Isexsit())  
  48.         {  
  49.             temp_x--;step--;  
  50.             goto operation4;  
  51.         }  
  52. operation2:  
  53.         temp_y++;step++;  
  54.         if(!Isexsit())  
  55.         {  
  56.             A[step].x=temp_x;  
  57.             A[step].y=temp_y;  
  58.             if(Isaim())  
  59.                 break;  
  60.         }  
  61.         else if(Isexsit())  
  62.         {  
  63.             temp_y--;step--;  
  64.             goto operation1;  
  65.         }  
  66. operation3:  
  67.         temp_x--;step++;  
  68.         if(!Isexsit())  
  69.         {  
  70.             A[step].x=temp_x;  
  71.             A[step].y=temp_y;  
  72.             if(Isaim())  
  73.                 break;  
  74.         }  
  75.         else if(Isexsit())  
  76.         {  
  77.             temp_x++;step--;  
  78.             goto operation2;  
  79.         }  
  80. operation4:  
  81.         temp_y--;step++;  
  82.         if(!Isexsit())  
  83.         {  
  84.             A[step].x=temp_x;  
  85.             A[step].y=temp_y;  
  86.             if(Isaim())  
  87.                 break;  
  88.         }  
  89.         else if(Isexsit())  
  90.         {  
  91.             temp_y++;step--;  
  92.             goto operation3;  
  93.         }  
  94.     }  
  95.     if(key==1)  
  96.         printf("%d/n",step+1);  
  97.     else  
  98.         printf("%d %d/n",temp_x,temp_y);  
  99.     return 0;  
  100. }  
  101. bool Isexsit()  
  102. {  
  103.     int i=0;  
  104.     while(i<50)  
  105.     {  
  106.         if(A[i].x==temp_x&&A[i].y==temp_y)  
  107.             return true;  
  108.         i++;  
  109.     }  
  110.     return false;  
  111. }  
  112. bool Isaim()  
  113. {  
  114.     if(key==1)  
  115.     {  
  116.         if(temp_x==x&&temp_y==y)  
  117.             return true;  
  118.         else return false;  
  119.     }  
  120.     else //key==2  
  121.     {  
  122.         if(step+1==N)  
  123.             return true;  
  124.         else return false;  
  125.     }  
  126. }  

运行结果如下:

 

欢迎各路牛人批评指正~



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值