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;
}
posted @ 2025-11-26 22:07  Ke_scholar  阅读(9)  评论(0)    收藏  举报