华为oj 之 蜂窝小区最短距离

/*
  学习了一种新的解题方法,很巧妙,利用坐标系来解题。
  参考:http://blog.csdn.net/nys001/article/details/12637201
*/
  1 #include <iostream>
  2 #include <fstream>
  3 #include <sstream>
  4 #include <cstdlib>
  5 #include <cstdio>
  6 #include <cstddef>
  7 #include <iterator>
  8 #include <algorithm>
  9 #include <string>
 10 #include <locale>
 11 #include <cmath>
 12 #include <vector>
 13 #include <cstring>
 14 #include <map>
 15 #include <utility>
 16 #include <queue>
 17 #include <stack>
 18 #include <set>
 19 #include <functional>
 20 using namespace std;
 21 typedef pair<int, int> PII;
 22 typedef long long int64;
 23 const int INF = 0x3f3f3f3f;
 24 const int modPrime = 3046721;
 25 const double eps = 1e-9;
 26 const int MaxN = 100010;
 27 const int MaxM = 30;
 28 const char Opt[4] = { '+', '-', '*', '/' };
 29 
 30 struct Node
 31 {
 32     int x, y, z;
 33 };
 34 
 35 
 36 /************************************************************************
 37 Description  : 初始化蜂窝小区信息
 38 Prototype    : void InitCellularDistrict(int iMaxSeqValue)
 39 Input Param  : iMaxSeqValue 蜂窝小区的最大值编号,注:编号从1开始
 40 Output Param : 无
 41 Return Value : 成功返回0,失败返回-1
 42 /************************************************************************/
 43 map<int, Node> posToCoords;
 44 int maxNum = 0;
 45 int InitCellularDistrict(int iMaxSeqValue)
 46 {
 47     if (iMaxSeqValue < 1 || iMaxSeqValue > 100000)
 48     {
 49         return -1;
 50     }
 51     maxNum = iMaxSeqValue;
 52     Node nd;
 53     nd.x = 0;
 54     nd.y = 0;
 55     nd.z = 0;
 56     posToCoords[1] = nd;
 57     for (int i = 2; i <= iMaxSeqValue; ++i)
 58     {
 59         int circleNum = 0;
 60         int cnt = 1;
 61         while (cnt < i)
 62         {
 63             ++circleNum;
 64             cnt += (6 * circleNum);
 65         }
 66         int side = (cnt - i) / circleNum;
 67         int sdPos = (cnt - i) % circleNum;
 68         switch (side)
 69         {
 70         case 0:
 71         {
 72             nd.x = circleNum;
 73             nd.z = sdPos;
 74             nd.y = -nd.x + nd.z;
 75             break;
 76         }
 77         case 1:
 78         {
 79             nd.z = circleNum;
 80             nd.y = sdPos;
 81             nd.x = nd.z - nd.y;
 82             break;
 83         }
 84         case 2:
 85         {
 86             nd.y = circleNum;
 87             nd.x = -sdPos;
 88             nd.z = nd.y + nd.x;
 89             break;
 90         }
 91         case 3:
 92         {
 93             nd.x = -circleNum;
 94             nd.z = -sdPos;
 95             nd.y = nd.z - nd.x;
 96             break;
 97         }
 98         case 4:
 99         {
100             nd.z = -circleNum;
101             nd.y = -sdPos;
102             nd.x = nd.z - nd.y;
103             break;
104         }
105         case 5:
106         {
107             nd.y = -circleNum;
108             nd.x = sdPos;
109             nd.z = nd.y + nd.x;
110             break;
111         }
112         default:
113             break;
114         }
115         posToCoords[i] = nd;
116     }
117     return 0;
118 }
119 
120 /************************************************************************
121 Description  : 计算出蜂窝小区指定两点(编号值)之间的最短距离
122 Prototype    : int GetShortestPathLength(int iFirstValue, int iSecondValue)
123 Input Param  : iFirstValue 起点编号值, iSecondValue 终点编号值
124 Output Param : 无
125 Return Value : 计算成功返回最短距离,失败返回-1
126 /************************************************************************/
127 int GetShortestPathLength(int iFirstValue, int iSecondValue)
128 {
129     if (iFirstValue < 1 || iFirstValue > maxNum || iSecondValue < 1 || iSecondValue > maxNum)
130     {
131         return -1;
132     }
133     Node nd1 = posToCoords[iFirstValue];
134     Node nd2 = posToCoords[iSecondValue];
135     int arr[3];
136     arr[0] = abs(nd1.x - nd2.x);
137     arr[1] = abs(nd1.y - nd2.y);
138     arr[2] = abs(nd1.z - nd2.z);
139     sort(arr, arr + 3);
140     int rel = arr[0] + arr[1];
141     return rel;
142 }
143 
144 /************************************************************************
145 Description  : 清空相关信息
146 Prototype    : void Clear()
147 Input Param  : 无
148 Output Param : 无
149 Return Value : 无
150 /************************************************************************/
151 void Clear()
152 {
153     posToCoords.clear();
154     maxNum = 0;
155 }
156 
157 int main()
158 {
159 #ifdef HOME
160     freopen("in", "r", stdin);
161     //freopen("out", "w", stdout);
162 #endif
163     
164     
165     InitCellularDistrict(60);
166     int rel = (GetShortestPathLength(19, 30)); // 5
167     InitCellularDistrict(60);
168     int rel1 = (GetShortestPathLength(1, 16)); // 2
169 
170 #ifdef HOME
171     cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << " ms" << endl;
172     _CrtDumpMemoryLeaks();
173 #endif
174     return 0;
175 }


 
原文地址:https://www.cnblogs.com/shijianming/p/5126122.html