【题目】
7 8 9
6 1 2
5 4 3
以上数字的排列规律,设1点的坐标是(0,0),x方向向右为正,y方向向下为正。例如,7的坐标为(-1,-1),2的坐标为(1,0),3的坐标为(1,1)。编程实现输入任意一点坐标(x,y),输出所对应的数字。
【算法分析】
观察队列 如把队列分成一圈一圈,如
7 8 9 7 8 9
6 1 2 就能分为 1 和 6 2
5 4 3 5 4 3
给圈层排序,发现第n个圈层右上角数字刚好是(2n-1)*(2n-1)。可以从这一点出发求出圈层的各个角点,由此可以确定其他各点的坐标。
【代码】
这是《程序员面试宝典》上的算法:
#include <stdio.h>
#define max(a, b) ((a) < (b) ? (b) : (a))
#define abs(a) ((a) > 0 ? (a) : -(a))
int foo(int x, int y)
{
int t = max(abs(x),abs(y));
int u = t + t;
int v = u - 1;
v = v * v + u;
if (x == -t)
{
v += u + t -y;
}
else if (y == -t)
{
v += 3 * u +x - t;
}
else if (y == t)
{
v += t - x;
}
else
{
v += y - t;
}
return v;
}
int main()
{
int x, y;
for (y=-4; y<=4; y++)
{
for (x=-4; x<=4; x++)
{
printf("%5d", foo(x, y));
}
printf("/n");
}
while (scanf("%d%d", &x, &y) == 2)
{
printf("%d ", foo(x, y));
}
return 0;
}下面是我按照【算法分析】写的foo函数
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 ;
}

4113

被折叠的 条评论
为什么被折叠?



