pta编程题19 Saving James Bond 2
其它pta数据结构编程题请参见:pta
和简单版本不同的是,简单版本只需判断能否到达岸边,而这个版本要求求出最少跳数的路径。
简单版本用dfs实现,而这道题用BFS实现。
注意:
岛半径为7.5,而不是15。另外注意一步跳到岸边的情况。
1 #include <iostream> 2 #include <vector> 3 #include <math.h> 4 using namespace std; 5 const int maxInt = 65535; 6 7 int N, D; 8 struct point 9 { 10 int x, y; 11 }G[100]; 12 13 struct queue 14 { 15 int arr[100]; 16 int head = 0; 17 int tail = 0; 18 }; 19 20 void enQueue(int i, queue& q); 21 int deQueue(queue& q); 22 bool isEmpty(queue q); 23 24 bool firstJump(int i); 25 bool jump(int i, int j); 26 bool toBank(int i); 27 bool bfs(int s, vector<int>& p); 28 bool shorter(vector<int> path1, vector<int> path2); 29 30 int main() 31 { 32 int i; 33 cin >> N >> D; 34 for (i = 0; i < N; i++) 35 cin >> G[i].x >> G[i].y; 36 37 bool first = true; 38 vector<int> path, minPath; 39 for (i = 0; i < N; i++) 40 { 41 if (firstJump(i) && bfs(i, path)) 42 { 43 if (first) //第一个可达到岸边的鳄鱼 44 { 45 minPath = path; 46 first = false; 47 } 48 else if (shorter(path, minPath)) 49 minPath = path; 50 } 51 } 52 53 if (first) cout << 0; //岸边不可达 54 else if (7.5 + D >= 50) //直接跳到岸边 55 cout << 1; 56 else { 57 cout << minPath.size() + 1 << endl; 58 for (i = minPath.size() - 1; i >= 0; i--) 59 { 60 int id = minPath[i]; 61 cout << G[id].x << " " << G[id].y << endl; 62 } 63 } 64 return 0; 65 } 66 67 bool firstJump(int i) 68 { 69 bool a = pow(G[i].x, 2) + pow(G[i].y, 2) <= pow((7.5 + D), 2); 70 return a; 71 } 72 73 bool jump(int i, int j) 74 { 75 return pow(G[i].x - G[j].x, 2) + pow(G[i].y - G[j].y, 2) <= D * D; 76 } 77 78 bool toBank(int i) 79 { 80 int x = G[i].x, y = G[i].y; 81 return (x <= D - 50 || x >= 50 - D || y <= D - 50 || y >= 50 - D); 82 } 83 84 bool shorter(vector<int> path1, vector<int> path2) 85 { 86 if (path1.size() != path2.size()) 87 return path1.size() < path2.size(); 88 else { 89 int a = path1[path1.size() - 1]; 90 int b = path2[path2.size() - 1]; 91 return pow(G[a].x, 2) + pow(G[a].y, 2) <= pow(G[b].x, 2) + pow(G[b].y, 2); 92 } 93 } 94 95 bool bfs(int s, vector<int>& p) 96 { 97 queue q; 98 enQueue(s, q); 99 bool marked[100] = {}; 100 int pathTo[100]; 101 marked[s] = true; 102 pathTo[s] = -1; 103 104 bool success = false; 105 int v, w; 106 while (!isEmpty(q)) 107 { 108 v = deQueue(q); 109 if (toBank(v)) //可以到岸边 110 { 111 success = true; 112 break; 113 } 114 for (w = 0; w < N; w++) 115 { 116 if (!marked[w] && jump(v, w)) 117 { 118 enQueue(w, q); 119 marked[w] = true; 120 pathTo[w] = v; 121 } 122 } 123 } 124 125 if (!success) return false; 126 vector<int> vec; 127 while (v != -1) 128 { 129 vec.push_back(v); 130 v = pathTo[v]; 131 } 132 p = vec; 133 return true; 134 } 135 136 void enQueue(int i, queue& q) 137 { 138 q.tail = (q.tail + 1) % 100; 139 q.arr[q.tail] = i; 140 } 141 142 int deQueue(queue& q) 143 { 144 q.head = (q.head + 1) % 100; 145 return q.arr[q.head]; 146 } 147 148 bool isEmpty(queue q) 149 { 150 return q.head == q.tail; 151 }