牛客春招刷题训练营 - 3.13题解 | C++
活动地址: 牛客春招刷题训练营 - 编程打卡活动
简单题:提取不重复的整数
和之前那道 字符串分隔 一样,考虑一个一个字符就简单得多了,当然这道题是一个一个数位地输出。
#include <iostream>
#include <set>
using namespace std;
int main() {
string s;
cin >> s;
int n = s.size();
set<char> st;
for(int i=n-1; i>=0; i--) {
if(!st.count(s[i])) {
cout << s[i];
st.insert(s[i]);
}
}
}
中等题:句子逆序
C++的STL库有个reverse函数,可以翻转一个vector数组,能直接解决这道题的需求。
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main() {
string x;
vector<string> a;
while(cin >> x) {
a.push_back(x);
}
reverse(a.begin(), a.end());
for(string x: a)
cout << x << " ";
}
困难题:迷宫问题
BFS经典题,建议不擅长BFS的小伙伴们好好消化一下这道题,可以参考一下我代码的框架,作为BFS的一个模版。
其实能用BFS做的题目都很套路,代码写出来其实也会长得差不多,套路就是走一套入队出队流程(在地图外的点、不能走的点或走过的点就跳过)。
不过这道题有个特殊点事需要记录一下有效路径。
我们可以用一个pre来维护一个pair的键值对,可以理解为一个单链表,把路径串起来。同时pre[{x, y}]有没有被赋值,也可以作为该点有没有走过的依据。
因为确保了每个点只会被走过一次,所以 pre[{x, y}] 也是对应一个唯一的前驱节点。那么走到终点之后只要倒着退回去,就能记录下整个有效路径。
PS:由于个人习惯,把地图整体移动为(1, 1)作为起点。(所以输出结果都要-1)
#include <iostream>
#include <map>
#include <queue>
#include <vector>
using namespace std;
using pii = pair<int, int>;
int main() {
int h, w;
cin >> h >>w;
vector<vector<int>> mp(h+1, vector<int>(w+1));
for(int i=1; i<=h; i++)
for(int j=1; j<=w; j++)
cin >> mp[i][j];
queue<pii> q;
q.push({1, 1});
vector<int> dx = {0, 1, 0, -1};
vector<int> dy = {1, 0, -1, 0};
// 记录一下上一个点
map<pii, pii> pre;
while(!q.empty()) {
auto [x, y] = q.front();
q.pop();
for(int i=0; i<4; i++) {
int xx = x + dx[i];
int yy = y + dy[i];
if(xx > h || yy > w || xx < 1 || yy < 1)
continue;
if(mp[xx][yy] == 1 || pre.count({xx, yy}))
continue;
q.push({xx, yy});
pre[{xx, yy}] = {x, y};
}
}
vector<pii> res;
for(pii i={h, w}; i!=(pii){1, 1}; i=pre[i]) {
res.push_back(i);
}
res.emplace_back(1, 1);
while(!res.empty()) {
auto [x, y] = res.back();
res.pop_back();
cout << "(" << x-1 << "," << y-1 << ")" << endl;
}
return 0;
}
#牛客春招刷题训练营#
查看4道真题和解析