2025年秋招-华为-11月19号开发岗
1.飞船扫描
BFS/DFS。
就是找 \(0\) 的联通块,但该联通块不能碰到边界,\(BFS/DFS\) 搜一下即可。
点击查看代码
#include <bits/stdc++.h>
using i64 = long long;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int n,m;
std::cin >> m >> n;
std::vector ve(n, std::vector<int>(m));
for(int i = 0; i < n; i += 1) {
for(int j = 0; j < m; j += 1) {
std::cin >> ve[i][j];
}
}
const int u[] = {1, -1, 0, 0};
const int v[] = {0, 0, 1, -1};
int ans = 0;
for(int i = 0; i < n; i += 1) {
for(int j = 0; j < m; j += 1) {
if(ve[i][j]) continue;
bool ok = true;
int cnt = 0;
std::queue<std::array<int,2>> pq;
pq.push({i, j});
ve[i][j] = 1;
while(pq.size()) {
auto [x, y] = pq.front();
pq.pop();
cnt += 1;
for(int k = 0; k < 4; k += 1) {
int dx = x + u[k];
int dy = y + v[k];
if(dx < 0 || dy < 0 || dx >= n || dy >= m) {
ok = false;
continue;
}
if(ve[dx][dy] == 0) {
ve[dx][dy] = 1;
pq.push({dx, dy});
}
}
}
if(ok) {
ans += cnt;
}
}
}
std::cout << ans << "\n";
return 0;
}
2.助手招募
模拟。
\(O(n^3)\) 枚举每个团队,判一下组成的人员中是否存在数值重复即可。
点击查看代码
#include <bits/stdc++.h>
using i64 = long long;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int n;
std::cin >> n;
std::vector has(3, std::vector<std::array<int,5>>());
for(int i = 0; i < n; i += 1) {
int id, t, r1, r2, r3, r4;
std::cin >> id >> t >> r1 >> r2 >> r3 >> r4;
has[--t].push_back({id, r1, r2, r3, r4});
}
int vis[101] {};
std::vector<std::array<int,3>> ans;
for(int i = 0; i < has[0].size(); i += 1) {
for(int p = 1; p < 5; p += 1) {
vis[has[0][i][p]] += 1;
}
for(int j = 0; j < has[1].size(); j += 1) {
bool ok = true;
for(int p = 1; p < 5; p += 1) {
if(vis[has[1][j][p]] && has[1][j][p]) ok = false;
vis[has[1][j][p]] += 1;
}
if(ok) {
for(int k = 0; k < has[2].size(); k += 1) {
ok = true;
for(int p = 1; p < 5; p += 1) {
if(vis[has[2][k][p]] && has[2][k][p]) {
ok = false;
break;
}
}
if(ok) {
ans.push_back({has[0][i][0], has[1][j][0], has[2][k][0]});
}
}
}
for(int p = 1; p < 5; p += 1) {
vis[has[1][j][p]] -= 1;
}
}
for(int p = 1; p < 5; p += 1) {
vis[has[0][i][p]] -= 1;
}
}
if(ans.empty()) {
std::cout << "-1\n";
} else {
sort(ans.begin(), ans.end());
for(auto &[x, y, z] : ans) {
std::cout << x << " " << y << " " << z << "\n";
}
}
return 0;
}
3.能量共振
思维。
把前缀和出现的最近的坐标记录一下,如果当前的前缀和 \(sum\) 在之前出现过,记 \(lst\) 为上次 \(sum\) 出现的位置,那么说明 \(lst + 1\sim i\) 之间的加起来又刚好为 \(0\) 了,所以 \(sum\) 才又出现,那么 \(i-lst\) 就是当前 \(i\) 最短的和为 \(0\) 的子数组,记 \(f_i = i-lst\),那么如果 \(f_{i-f_i}\) 也存在的话,那这两就构成可对称分割数组,更新一下答案即可。
点击查看代码
#include <bits/stdc++.h>
using i64 = long long;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int n;
std::cin >> n;
std::vector<int> a(n);
for(int i = 0; i < n; i += 1) {
std::cin >> a[i];
}
std::map<int,int> mp;
mp[0] = -1;
int ans = n, num = 0;
i64 sum = 0;
std::vector<int> f(n);
for(int i = 0; i < n; i += 1) {
sum += a[i];
if(mp.count(sum)) {
f[i] = i - mp[sum];
if(i - f[i] >= 0 && f[i - f[i]]) {
int x = f[i] + f[i - f[i]];
if(x < ans) {
ans = x;
num = 1;
} else if(x == ans) {
num += 1;
}
}
}
mp[sum] = i;
}
if(!num) {
std::cout << "-1 -1\n";
} else {
std::cout << ans << " " << num << "\n";
}
return 0;
}

浙公网安备 33010602011771号