UVA808(对蜂窝建立坐标系)

这个题我是通过建立坐标系加找规律做出来的,个人感觉难点是建立坐标系,所以我将着重讲一下坐标系是怎么建立的

建立坐标系:

如果你有兴趣的话,你可以将他给的图沿横线延长,这样一个正六边形就会被分为上下两部分,我们在从中间画一条

竖线,就会把一个正六边形分为四部分如下图

红色的点是原点O,标1的是单位长度为1,2则是单位长度为2(原谅我把图画的这么难看)

这就是我们建立的坐标系

UVA808(对蜂窝建立坐标系)_第1张图片


知道了我们坐标系的样子下面就是实施建造,流程如下

1、以第一个点作为原点录入

2、将第二个点也即下一次循环的起始点录入

3、移动,移动方向分别为左上、上、右上、右下、下

4、下一2单位长度到达下一个循环

5、向左下移动直至到达原点正下方

我们解题的规律则是当x大于等于y的差时,值为x,否则值为x + (y - x) / 2

x,y分别代表X轴的差和y轴的差

AC代码

#include
#include

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;
}


你可能感兴趣的:(解题报告)