华为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 }