Chinaunix首页 | 论坛 | 博客
  • 博客访问: 326173
  • 博文数量: 78
  • 博客积分: 2536
  • 博客等级: 少校
  • 技术积分: 600
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-29 01:50
文章分类

全部博文(78)

文章存档

2011年(1)

2010年(17)

2009年(52)

2008年(8)

我的朋友

分类: C/C++

2009-10-20 11:12:36

问题描述:

21 22 ....
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)。编程实现输入任意一点坐标 (x,y),输出所对应的数字。[Finland 某著名通信设备公司 2005 年面试题]

螺旋队列的样子如下图:

从图中我们发现两大规律:
1、螺旋规律(红线)
2、奇数平方规律(紫线)

问题解决:

从紫线突破。从图中不难发现,右上角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);

注意:x=-t区,u=vc+3*x-y,其中x的系统为3是怎么来的?
这个是由边长来算出来的,我们知道每个方形的边长=2t,那么在x=-t区,边长的中点的坐标(即y=0)为:
vc-边长-边长/2=vc-2t-2t/2=vc-3t,即得当x=-t,y=0时u=vc+3*x

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

程序实现:

  1. #include
  2. #include
  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.      }
阅读(826) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~