Chinaunix首页 | 论坛 | 博客
  • 博客访问: 605637
  • 博文数量: 165
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1554
  • 用 户 组: 普通用户
  • 注册时间: 2013-10-23 22:57
个人简介

我本仁慈,奈何苍天不许

文章分类

全部博文(165)

文章存档

2018年(1)

2016年(33)

2015年(5)

2014年(34)

2013年(92)

分类: LINUX

2014-01-19 14:34:42


根据圈子数n,请输出螺旋队列:如下图
 
为了更好的讲解这个算法,我另外画一个图
 
首先说一下这个图
我们把图放在x,y轴上,然后右边是x正半轴,左边是x的负半轴。上边是y的正半轴,下边是y的负半轴
然后整个图被一个大大的红叉划分成上下左右四块区域。

开始分析:
1. 代码很明显是根据(x,y)坐标得到数据的。所以我们写出主函数的代码。
2. 再写螺旋函数的时候,我们很明显的发现rightUp=(2*n+1)*(2*n+1)并且左下角leftDown=(2*n)*(2*n)+1
3. 那么我们就应该先求n=max(abs(x),abs(y));
4. 然后求出左下角和右上角的值。(这样的话,与他同行同列的值都能求的【除了右上角下边的值】)
5. 然后根据n值与x,y的比较,进行区域的划分。没错,就是划分为上下左右四个区域。
6. 那么现在有一个比较大的问题,就是我们可以根据右上和左下的数据得到同行或者同列的值。但是我们不能根据右上角的值得到右上角下边的值【即右区域的值】,因为可以说这个区域值与左下角值与右上角值没有关系【实际上是有关系的,为了简单,我们不再讨论】。那么这个问题怎么解决呢?实际上很简单。我们只要先判断上下左即可,最后判断右的时候,x,y相等的情况已经被前面三个过滤过了。就可以了。所以我们定义了下面的代码
#define max(a,b) ((a)>(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
7.所以说,数学功力有多深,决定程序员走多远。这是我们老师说的。我越来越体会到了这句话的意思。

代码如下


  1. #include  
  2. #define max(a,b) ((a)>(b)?(a):(b))  
  3. #define abs(x) ((x)>0?(x):-(x))  
  4. int spiral(int x,int y)  
  5. {  
  6.     int result;//要返回的结果  
  7.     int n=max(abs(x),abs(y));//返回较大的数值,既是现在所在位置的层数n  
  8.     int rightUp=(2*n+1)*(2*n+1);//返回所在层数的右上角的值,也是正方形中的最大值  
  9.     int leftDown=4*n*n+1;//返回所在层数的左下角的值  
  10.     if(n==-x){  
  11.         result=leftDown+abs(x-y);  
  12.     }else if(n==y){  
  13.         result=rightUp-abs(x-y);  
  14.     }else if(n==-y){  
  15.         result=leftDown-abs(x-y);  
  16.     }else{  
  17.         result=leftDown-2*n-abs(x+y);  
  18.     }  
  19.     return result;  
  20. }  
  21. int main(void)  
  22. {  
  23.     // 输出螺旋队列  
  24.     int n,x,y;  
  25.     printf("请输入螺旋队列的圈数n:");  
  26.     scanf("%d",&n);  
  27.     for(y=n;y>=-n;y--)  
  28.     {  
  29.         for(x=-n;x<=n;x++)  
  30.         {  
  31.             printf("%8d",spiral(x,y));  
  32.         }  
  33.         printf("\n");  
  34.     }  
  35.     return 0;  
阅读(1199) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~