华为春招笔试打怪兽
优先队列,按照当前已经消灭的怪兽数量倒序排列,限制每个位置访问的次数防止循环
#include<iostream> #include<vector> #include<cmath> #include<algorithm> #include<queue> using namespace std; int cmp(int a, int b) { return a > b; } struct Node { int x, y, step, cnt;//位置x,y,当前步数,当前消灭的怪兽个数 bool operator<(const Node& a) const { if(cnt != a.cnt) return cnt < a.cnt; return step > a.step; } }; int main() { int n, cnt = 0; vector<int>tmp, notUsed;//notused记录当前没有消灭的怪兽的等级 while (cin >> n) { //if (n == -1)break; if (n >= 2) notUsed.push_back(n); tmp.push_back(n); } cnt = (int)sqrt(tmp.size()); sort(notUsed.begin(), notUsed.end(), cmp); int maxCnt = notUsed.size(); if (maxCnt == 0) { cout << "0" << endl; return 0; } vector<vector<int>>v(cnt, vector<int>(cnt)), flag(cnt, vector<int>(cnt, 0)); int k = 0; for (int i = 0; i < cnt; i++) { for (int j = 0; j < cnt; j++) { v[i][j] = tmp[k++]; } } priority_queue<Node>pq; if (v[0][0] == notUsed.back())//初始位置是等级最低的怪兽 { pq.push({ 0,0,0,1 }); //flag[0][0] = 1; v[0][0] = 0; notUsed.pop_back(); } else if (v[0][0] > notUsed.back() || v[0][0] == 0)//高等级怪兽或者陷阱 { cout << "-1" << endl; return 0; } else//陆地 { pq.push({ 0,0,0,0 }); } int dir[4][2] = { 1,0,0,1,-1,0,0,-1 }; while (!pq.empty()) { Node a = pq.top(); pq.pop(); flag[a.x][a.y]++;//更新当前位置访问的次数 if (notUsed.size() == 0)//怪兽消灭完 { cout << a.step << endl; return 0; } if (flag[a.x][a.y] > maxCnt)//经过某位置超过一定次数,则产生循环 { cout << "-1" << endl; return 0; } for (int i = 0; i < 4; i++) { int dx = a.x + dir[i][0]; int dy = a.y + dir[i][1]; if (dx >= 0 && dx < cnt && dy >= 0 && dy < cnt) { if (v[dx][dy] == 1) { pq.push({ dx, dy, a.step + 1, a.cnt }); } else if (v[dx][dy] == notUsed.back()) { v[dx][dy] = 1; pq.push({ dx, dy, a.step + 1, a.cnt+1 }); notUsed.pop_back(); } } } } cout<<"-1"<<endl; return 0; }