螺旋队列

来源:互联网 发布:手机淘宝10.0 编辑:程序博客网 时间:2024/04/30 00:08

作者:hustwing         hustwing@126.com  MSN: hustwing@hotmail.com

我最先在《程序员面试宝典》上看到的一个题目:

【题目】
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,0),x方向向右为正,y方向向下为正。例如,7的坐标为(-1,-1),2的坐标为(1,0),3的坐标为(1,1)。编程实现输入任意一点坐标(x,y),输出所对应的数字。

【题目完】

这道题第一次拿到手时,还着实花了我一些时间来思考。如果这算是一次面试,那我还真是有些失败。

我自己想到的一个实现是,先计算出每个正方形(以1为中心,可以将数字看做是一圈一圈的正方形),先算出每个正方形的右上角的顶点数字(1,9,25),这些数实际上是((2n+1)^2),再根据这些数字的坐标来推算这一圈上的其它数字的坐标。前几天网上搜了一下,发现还不只我一个人这么想,别人已经实现了我的想法,我也只把别人的稍稍消化一下,就直接"拿来主义"了。一向喜欢简洁易懂的代码,下面的代码,只要画个图简单地分析一下就明白了,呵呵,很好很强大。

----------------------------------------------------------------------------------------------------------------------------------------

#define max(a,b) ((a)<(b)?(b):(a))
#define abs(a) ((a) > 0 ?(a):-(a))
int foo(int x,int y)
{
    if (0==x && 0==y)
    {
        return 1;
    }
    int t = max(abs(x),abs(y));
    int u = (2*t + 1)*(2*t +1);
    //依次考察正方形的每条边线
    if (y == -t)
    {
        u -= t - x;
    }
    else if (x == -t)
    {
        u -= (t + y + 2*t);
    }
    else if (y == t)
    {
        u -= (t + x + 4*t);
    }
    else
    {
        u -= (t - y + 6*t);
    }
    return u;
}

#define N 3
int _tmain(int argc, _TCHAR* argv[])
{
    int x, y;
    for (y=-N; y<=N; y++)
    {
        for (x=-N; x<=N; x++)
        {
            printf("%4d", foo(x, y));
        }
    printf(" /n");
    }
    return 0;
}

--------------------------------------------------------完整代码,包括验证代码--------------------------------------------------------------

最后,参考网址给出来:http://www.diybl.com/course/3_program/c++/cppjs/2008219/100341.html

原创粉丝点击