• 螺旋队列问题之一


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

       21   22   23   24   25
       20    7    8    9   10
       19    6    1    2   11
       18    5    4    3   12
       17   16   15   14   13

      解析:从数字排列可以得到如下规律,以1为中心点,数字有规律地一层一层往外扩展。第0层为1,第1层为2~9,第2层为10~25......

         第n层的最后一个数是(2*n+1)2

         所以解题关键可分为几步,先获取层数n,然后根据坐标算出与当层最后一个数的相对位置即可。

    具体函数实现如下:

    int fun(int x,int y)
    {
            int layer=max(abs(x),abs(y));    //计算出该坐标属于哪一层
            int base=2*layer+1;
            int key;
            if(y==-layer)                    //上边的一行
              key=base*base+y+x;
            else if(y==layer)         //下面的一行
              key=base*base-2*base+2-(y+x);
            else if(x==-layer && abs(y)!=layer)      //左边的一行
              key=base*base-base+1-(-x+y);
            else if(x==layer && abs(y)!=layer)    //右边的一行
              key=base*base-3*base+3-(x-y);
            else
              {
                    printf("error");
                    return -1;
              }
            return key;
    }

      从函数可以看出,一层有四个边,要分别讨论不同的情况。不要想用一条公式就把所有规律都表示出来。

    测试代码可用如下:

    #include <stdio.h>
    
    #define abs(a) ((a)>0?(a):-(a))
    #define max(x,y) ((abs(x))>abs(y)?(abs(x)):(abs(y)))
    
    int fun(int x,int y)
    {
            int layer=max(abs(x),abs(y));
            int base=2*layer+1;
            int key;
            if(y==-layer)
              key=base*base+y+x;
            else if(y==layer)
              key=base*base-2*base+2-(y+x);
            else if(x==-layer && abs(y)!=layer)
              key=base*base-base+1-(-x+y);
            else if(x==layer && abs(y)!=layer)
              key=base*base-3*base+3-(x-y);
            else
              {
                    printf("error");
                    return -1;
              }
            return key;
    }
    
    int main(void)
    {
            int x,y;
            int range=4;
            for(y=-range;y<=range;y++)
            {
                    for(x=-range;x<=range;x++)
                    {
                            printf("%5d",fun(x,y));
                    }
                    printf("
    ");
            }
            printf("请输入两个数:");        
            while(scanf("%d%d",&x,&y)==2)
            {
                    printf("%d
    ",fun(x,y));
                    printf("请输入两个数:");
            }
            return 0;
    }

    结果测试如下:

    [root@master tmp]# ./1
    73 74 75 76 77 78 79 80 81
    72 43 44 45 46 47 48 49 50
    71 42 21 22 23 24 25 26 51
    70 41 20  7  8  9 10 27 52
    69 40 19  6  1  2 11 28 53
    68 39 18  5  4  3 12 29 54
    67 38 17 16 15 14 13 30 55
    66 37 36 35 34 33 32 31 56
    65 64 63 62 61 60 59 58 57
    请输入两个数:4 2
    55
    请输入两个数:1 1
    3
    请输入两个数:2 4
    59
    请输入两个数:3 3
    31
    请输入两个数:3 -3
    49

     程序猿必读

  • 相关阅读:
    php中文乱码处理方法
    Zend 官方框架增加 Swoole 协程支持 !
    矩阵行列式的向量表示
    ArduinoYun教程之ArduinoYun硬件介绍
    MIT 操作系统实验 MIT JOS lab1
    java File_encoding属性
    Java入门 第一季第五章 编程练习解析
    android 三种定位方式
    6.30
    OpenJudge百炼习题解答(C++)--题3142:球弹跳高度的计算
  • 原文地址:https://www.cnblogs.com/longzhongren/p/4380192.html
Copyright © 2020-2023  润新知