UVA808(对蜂窝建立坐标系)
这个题我是通过建立坐标系加找规律做出来的,个人感觉难点是建立坐标系,所以我将着重讲一下坐标系是怎么建立的
建立坐标系:
如果你有兴趣的话,你可以将他给的图沿横线延长,这样一个正六边形就会被分为上下两部分,我们在从中间画一条
竖线,就会把一个正六边形分为四部分如下图
红色的点是原点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. ",a,b,result); } return 0; }
上一篇:
IDEA上Java项目控制台中文乱码