网易笔试
题1
n 个顶点的无向图判断能否从 start 连通到 end
const int INF = 0x3f3f3f3f;
class Solution {
public:
vector<vector<int>> edges;
vector<int> dist;
void bfs(int s) {
dist[s] = 0;
queue<int> q;
q.push(s);
while (!q.empty()) {
int u = q.front();
q.pop();
for (int v : edges[u]) {
if (dist[v] == INF) {
dist[v] = dist[u] + 1;
q.push(v);
}
}
}
}
bool validPath(int n, vector<vector<int> >& sides, int start, int end) {
edges = vector<vector<int>>(n);
dist = vector<int>(n, INF);
for (auto &e : sides) {
edges[e[0]].push_back(e[1]);
edges[e[1]].push_back(e[0]);
}
bfs(start);
return dist[end] != INF;
}
};
/*
4,[[0,1],[1,2],[2,3],[3,0]],0,2
true
*/ 题2
三个数能否只用加减乘除凑24,可以交换数字位置
class Solution {
constexpr static double eps = 1e-5;
public:
bool dfs(vector<int>& nums, double res) { // init : dfs(nums, nums[0/1/2]
for (int &i : nums) {
if (i == -1)
continue;
int pre = i;
i = -1;
if (dfs(nums, res + pre) || dfs(nums, res - pre) || dfs(nums, res * pre) || dfs(nums, res / pre))
return true;
i = pre;
}
if (count(begin(nums), end(nums), -1) == 3 && abs(res - 24.0) < eps)
return true;
return false;
}
bool compute24(vector<int>& inputNumbers) {
for (int i = 0; i < 3; i++) {
int pre = inputNumbers[i];
inputNumbers[i] = -1;
if (dfs(inputNumbers, pre))
return true;
inputNumbers[i] = pre;
}
return false;
}
};
/*
2 4 12
true
1 1 1
false
*/ 题3
M*N的迷宫有一些位置有宝藏,两个人走迷宫最大能获得的宝藏数.
这题有点小坑,不能贪心两次dp做,所以我暴力枚举第一个人走的路径然后 dp 求第二个人能拿的最大宝藏,不知道有没有更好的做法。。下面代码给了个不能贪心的用例。。
麻了贪心找了一个小时bug。
#include <bits/stdc++.h>
#define IO ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
using namespace std;
using vi = vector<int>;
using vvi = vector<vi>;
int M, N, K;
vvi mp;
int ans = 0;
int getMoney() {
vvi dp = mp;
for (int i = 1; i <= M; i++) {
for (int j = 1; j <= N; j++) {
if (j == 1 or dp[i - 1][j] > dp[i][j - 1]) {
dp[i][j] += dp[i - 1][j];
}
else {
dp[i][j] += dp[i][j - 1];
}
}
}
return dp[M][N];
}
void dfs(int x, int y, int sum) {
sum += mp[x][y];
int tmp = mp[x][y];
mp[x][y] = 0;
if (x + 1 <= M) {
dfs(x + 1, y, sum);
}
if (y + 1 <= N) {
dfs(x, y + 1, sum);
}
if (x == M and y == N) {
int c = getMoney();
if (sum + c > ans)
ans = sum + c;
}
mp[x][y] = tmp;
}
int32_t main() {
IO;
cin >> M >> N >> K;
mp = vector<vector<int>> (M + 1, vector<int>(N + 1, 0));
while (K--) {
int x, y, z;
cin >> x >> y >> z;
mp[x][y] += z;
}
dfs(1, 1, 0);
cout << ans << "\n";
return 0;
}
/*
6 5 9
1 4 1000
2 1 1000
2 2 1
2 3 1000
2 4 1
2 5 1000
3 3 1000
3 5 1
4 5 1
ans=5004(不能贪心)
3 5 10
1 2 1
1 3 5
1 5 10
2 1 8
2 2 10
2 3 4
2 4 3
3 1 10
3 3 2
3 4 8
ans=49
*/题4
第一行:N层楼,从A出发到B的最小按开关次数
第二行:N个数,k[i] 表示第 i 层的时候按开关电梯可以上行或者下行 k[i] 层,如果目标楼层 i+k[i] 或者 i-k[i] 不在 1~N 之间,按开关无效
#include <bits/stdc++.h>
#define IO ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
using namespace std;
int32_t main() {
IO;
int n, a, b;
cin >> n >> a >> b;
--a;
--b;
vector<int> k(n);
vector<int> vis(n, -1);
for (int i = 0; i < n; i++) {
cin >> k[i];
}
queue<int> q;
q.push(a);
vis[a] = 0;
while (!q.empty()) {
int cur = q.front();
q.pop();
int nx1 = cur - k[cur];
int nx2 = cur + k[cur];
if (0 <= nx1 and nx1 < n and vis[nx1] == -1) {
q.push(nx1);
vis[nx1] = vis[cur] + 1;
}
if (0 <= nx2 and nx2 < n and vis[nx2] == -1) {
q.push(nx2);
vis[nx2] = vis[cur] + 1;
}
}
cout << vis[b] << "\n";
return 0;
}
/*
5 1 5
3 3 1 2 5
ans=3
*/#网易笔试##网易##笔经#
SHEIN希音公司福利 256人发布