UVa 808 (建坐标系、找规律) Bee Breeding
题意:
如图,按照图中的规律给这些格子编号。给出两个格子的编号,求从一个格子到另一个格子的最少步数。(一步只能穿过有有公共边的格子)
分析:
根据高中数学知识,选任意两个不共线的向量,就能表示平面上所有点。
像这样建立坐标系,根据图中的规律算出所有点的坐标。
推理也好,找找规律也好,不难发现
- 第一、三象限的点(x, y)到原点的距离为 |x| + |y|
- 第二、四象限的点(x, y)到原点的距离为 max{|x|, |y|}
递推点的坐标的时候也是比较注意细节的,否则很容易出错。
1 #include <cstdio> 2 #include <cmath> 3 #include <algorithm> 4 using namespace std; 5 const int maxn = 10000; 6 7 struct Point 8 { 9 int x, y; 10 Point(int x=0, int y=0):x(x), y(y) {} 11 }p[maxn + 330]; 12 13 int dx[] = {-1, -1, 0 , 1 , 1 , 0 }; //六个方向 14 int dy[] = {0 , 1 , 1 , 0 , -1, -1}; 15 int pos; 16 17 void cal(int dir, int l) //按照dir方向递推l个格子的坐标 18 { 19 pos++; 20 while(l--) 21 { 22 p[pos] = Point(p[pos-1].x+dx[dir], p[pos-1].y+dy[dir]); 23 pos++; 24 } 25 pos--; 26 } 27 28 void Init() 29 { 30 p[2] = Point(1, -1); 31 pos = 2; 32 for(int l = 1; l <= 58; ++l) 33 { 34 for(int dir = 0; dir < 4; ++dir) 35 cal(dir, l); 36 cal(4, l+1); 37 cal(5, l); 38 } 39 } 40 41 int main() 42 { 43 Init(); 44 45 int n, m; 46 while(scanf("%d%d", &n, &m) == 2 && n) 47 { 48 int x = p[n].x - p[m].x; 49 int y = p[n].y - p[m].y; 50 int ans; 51 if((x<0&&y>0) || (x>0&&y<0)) ans = max(abs(x), abs(y)); 52 else ans = abs(x+y); 53 54 printf("The distance between cells %d and %d is %d.\n", n, m, ans); 55 } 56 57 return 0; 58 }