在《程序员面试宝典》上看到的一个例题,尝试做了一下发现居然花了不少时间才做出来,心底不由得升起了一阵的小恐慌——真正的笔试面试时哪来的很多时间给我来想啊!得勤加练习了!题目是这样的:  

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的坐标为(1,0),3的坐标为(1,1)。编程实现输入任意一点坐标(x,y),输出所对应的数字。

    分析:可以以每圈数字(如1在第0圈,2在第1圈,11在第2圈)的某个点为基准点来推算出,这里和书上的算法一样选择每圈的右下角点,设圈数为max,其通配式为(2*max-1)*(2*max-1)+2*max,然后分本圈的top边、left边、bottom边、right边来进行计算,则可有如下实现代码(Dev-C++ 4.9.9.2编译):


#include

int fun(int x, int y)

{

    int max = (abs(x) >= abs(y)) ? abs(x) : abs(y);

    int u = max + max;

    int val = u - 1;

    val = val * val + u;         // 每一圈的右下角的点的值

    /先确定点所在边的正中间的点的值/

    if (max == -y)               // 若在本圈的top边

    {

         val += 5 * max + x;

    }

    else if (max == -x)          // 若在本圈的left边

    {

         val += 3 * max - y;

    }

    else if (max == y)           // 若在本圈的bottom边

    {

         val += max - x;

    }

    else                         // 若在本圈的right边

    {

        val += y - max;

    }

    return val;

}

int main()

{

    while(true)

    {

        int x;

        int y;

        std::cout << "请输入横坐标:";

        std::cin >> x;

        std::cout << "请输入纵坐标:";

        std::cin >> y;

        std::cout << "此坐标处的数:" << fun(x,y) << std::endl;

    }

    return 0;   

}