作者:hustwing [email protected] MSN: [email protected]
我最先在《程序员面试宝典》上看到的一个题目:
【题目】
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