题意描述:
根据下面的图片你就可以看出来,就是根据下面右边图中的数字,求出对应左边图上的坐标。
算法分析:
先看下面一幅图,然后进行分析。
1、首先我们可以看出中间是一个,第二圈是6个,第三圈是12个,这就是规律。其实就是一圈圈六边形,边长分别为1,2,3,4.。。。。这样我们通过n就可以知道当前这个点在第几圈。
2、然后我们看x轴,也就是红色的那几条中的带黑色箭头标有x的线,经过1,7,19.。。。不就是1 + 6 =7, 1 + 6 + 12 = 19, 1+ 6 + 12 + 18 = 37.........我们可以将这些点当做每一圈的最后一个点,然后往前推,找到n在这个圈上的位置。
3、然后我们可以看到整个图形被三条红线分成了6个角度,我们可以根据当前圈的最后一个点减去n,得到程序中的k。根据k我们可以计算出这个点在哪条边上,到这里算法基本上讲完了。以为我们很容易算出三条红线上的坐标,我们又知道那个点在哪条边上的哪个点,就很容易推出坐标。
4、从图中可以看出,如果落在六边形的最右的那条边,往上面是x不变,y--;然后右上方那条边,y不变,x--;然后是左上方,x--,y++。后面就不用说了吧。。。。。
举个例子吧。
n = 8;
在第2圈
最后一个点是19(1 + 6 + 12),19的坐标是(2,0). k = 19 - 8 = 11.
(k + i - 1)/ i (k 是 当前点距离终点的距离,i是第几圈),这样可以算出这个点在哪条边上。为何要加上i-1呢,就是为了让第一条边是1。。。
这样我们就得出,8在右下方那条边上。那8是这条边上的第几个呢? 11 - 5 * 2 = 1.就是第一个,那么我们又知道9这点的坐标就是(0,2)(其实就是(0,i)),然后往右边走就是x++,y--。往右边走一个,所以就得到(1,1)啦。
有点麻烦啊,暂时想不到简便的了。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int main()
{
int n,i,m,k,t;
while (scanf("%d", &n) != EOF)
{
m = 1;
for (i = 0; ; ++ i)
{
m = m + i * 6;
if (m >= n)
{
k = m - n;
break;
}
}
if (k == 0)
{
printf("%d 0\n", i);
}
else
{
t = (k + i - 1) / i;
if (t <= 1)
{
printf("%d %d\n", i, -k);
}
else if (t <= 2)
{
printf("%d %d\n", 2 * i - k, - i);
}
else if (t <= 3)
{
printf("%d %d\n", 2 * i - k, k - 3 * i);
}
else if (t <= 4)
{
printf("%d %d\n", - i, k - 3 * i);
}
else if (t <= 5)
{
printf("%d %d\n", k - 5 * i, i);
}
else
{
printf("%d %d\n", k - 5 * i, 6 * i - k);
}
}
}
return 0;
}