这个题我是通过建立坐标系加找规律做出来的,个人感觉难点是建立坐标系,所以我将着重讲一下坐标系是怎么建立的
建立坐标系:
如果你有兴趣的话,你可以将他给的图沿横线延长,这样一个正六边形就会被分为上下两部分,我们在从中间画一条
竖线,就会把一个正六边形分为四部分如下图
红色的点是原点O,标1的是单位长度为1,2则是单位长度为2(原谅我把图画的这么难看)
这就是我们建立的坐标系
知道了我们坐标系的样子下面就是实施建造,流程如下
1、以第一个点作为原点录入
2、将第二个点也即下一次循环的起始点录入
3、移动,移动方向分别为左上、上、右上、右下、下
4、下一2单位长度到达下一个循环
5、向左下移动直至到达原点正下方
我们解题的规律则是当x大于等于y的差时,值为x,否则值为x + (y - x) / 2
x,y分别代表X轴的差和y轴的差
AC代码
#include<stdio.h>
#include<stdlib.h>
const int maxn = 20000 + 10;
const int dir[5][2] = {{-1,1},{0,2},{1,1},{1,-1},{0,-2}};
struct Point
{
int x,y;
Point(){}
Point(int x,int y)
{
this->x = x;
this->y = y;
}
}P[maxn]; //点集
//以第一个点为原点,初始化坐标系
void init()
{
int cnt = 1,x = 0,y = 0;
//以下两行绘制了坐标系的原点
P[cnt++] = Point(x,y);
y -= 2;
P[cnt++] = Point(x,y); //记录下一个循环的起点
for(int i = 1; i <= 60; i++) //通过60次的循环完全可以绘制出60个点
{
for(int j = 0; j < 5; j++) //改变方向
{
for(int k = 0; k < i; k++) //每个方向上走几步
{
x += dir[j][0];
y += dir[j][1]; //移动
P[cnt++] = Point(x,y);
}
}
//抵达下一个循环
y -= 2;
P[cnt++] = Point(x,y);
for(int j = 0; j < i; j++)
{
x--; y--;
P[cnt++] = Point(x,y);
}
}
}
int main()
{
int a,b;
init();
while(scanf("%d%d",&a,&b) == 2 && a || b )
{
int result;
int x = abs(P[a].x - P[b].x);
int y = abs(P[a].y - P[b].y);
if( x >= y) result = x; //该公式可以找规律找到
else result = x + (y - x) / 2;
printf("The distance between cells %d and %d is %d.\n",a,b,result);
}
return 0;
}