华为笔试 华为笔试题 0410
笔试时间:2024年04月10日
历史笔试传送门:
第一题
题目:云服务计费
编写一个程序为某云服务计算客户话单,输入为某云服务的计费日志和各种计费因子的计费单价的列表,计费日志内容包含时间戳、客户标识、计费因子、计费时长4个字段。日志中如果同一客户同一计费因子在相同时间戳上报多次话单只能计费一次,选先上报的日志计费。计算每个客户的话单总费用。
输入描述
第1行表示计费日志的条数n,是一个正整数,范围是1<=n<=1000;
第2到n+1行表示云服务的计费日志,共4列,第1列表示时间戳(是一个数字字符串,长度为10) 、第2列表示客户标识(是一个字符串,长度为1-16),第3列表示计费因子 (是一个字符串,长度为1-16,计费因子查不到时认为计费因子单价是0),第四列表示计费时长时长(范围为0-100,当计费时长不在范围内要认为是计费日志有问题,当成计费为0处理),这4个字段使用迈号分隔;
第n+2行表示计费因子的数量m,m是一个正整数,范围是1<=m<=100;
第n+3到n+3+m行表示各种计费因子的计费单价的列表,该表有2列,第1列表示计费因子 (是一个字符串,长度为1-16),第2列表示单价(是一个正整数,范围为1~100),这2个字段使用逗号分。
输出描述
每个客户的话单总费用,共2列,第1列表示客户名,第2列表示话单费用,2列用逗号分割,输出按客户标识字典序升序排序。
样例输入
5
1627845600,client1,factorA,10
1627845605,client2,factorB,15
1627845610,ciient1,factorA,5
1627845610,client1,factorB,8
1627845620.client2,factorB,20
2
factorA,5
factorB,7
样例输出
client1,131
client2,245
参考题解
通过stringstream对输入的字符串进行拆分;通过set进行判断是否存在相同的时间戳客户和计费因子;通过map进行存储不同的客户和计费因子;最后合并统计出各个用户的消费。
C++:[此代码未进行大量数据的测试,仅供参考]
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n; cin >> n;
string a[5];
map<pair<string, string>, int> h1;
set<string> ses;
while (n -- )
{
string s, t;
cin >> s;
stringstream ss(s);
int k = 0;
while(getline(ss, t, ','))
a[k ++] = t;
string ts = a[0] + a[1] + a[2];
if(ses.count(ts)) continue;
else ses.insert(ts);
int tt = stoi(a[3]);
if(tt< 0 || tt > 100) continue;
h1[{a[1], a[2]}] += tt;
}
int m; cin >> m;
unordered_map<string, int> h2;
while (m -- )
{
string s, t;
cin >> s;
int k = 0;
stringstream ss(s);
while(getline(ss, t, ','))
a[k ++] = t;
h2[a[0]] = stoi(a[1]);
}
map<string, int> h3;
for(auto &[k, v] : h1)
{
string client = k.first, factor = k.second;
h3[client] += (h2[factor] * v);
}
vector<pair<string, int>> res;
for(auto &[k, v] : h3) res.push_back({k, v});
sort(res.begin(), res.end());
for(int i = 0; i < res.size(); i ++)
cout << res[i].first << "," << res[i].second << endl;
return 0;
}
Java:[此代码未进行大量数据的测试,仅供参考]
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
String[] a = new String[5];
Map<Map.Entry<String, String>, Integer> h1 = new HashMap<>();
Set<String> ses = new HashSet<>();
while (n-- > 0) {
String s = br.readLine();
String[] parts = s.split(",");
for (int i = 0; i < parts.length; i++) {
a[i] = parts[i];
}
String ts = a[0] + a[1] + a[2];
if (ses.contains(ts)) continue;
else ses.add(ts);
int tt = Integer.parseInt(a[3]);
if (tt < 0 || tt > 100) continue;
Map.Entry<String, String> key = new AbstractMap.SimpleEntry<>(a[1], a[2]);
h1.put(key, h1.getOrDefault(key, 0) + tt);
}
int m = Integer.parseInt(br.readLine());
Map<String, Integer> h2 = new HashMap<>();
while (m-- > 0) {
String s = br.readLine();
String[] parts = s.split(",");
for (int i = 0; i < parts.length; i++) {
a[i] = parts[i];
}
h2.put(a[0], Integer.parseInt(a[1]));
}
Map<String, Integer> h3 = new HashMap<>();
for (Map.Entry<Map.Entry<String, String>, Integer> entry : h1.entrySet()) {
String client = entry.getKey().getKey();
String factor = entry.getKey().getValue();
h3.put(client, h3.getOrDefault(client, 0) + (h2.get(factor) * entry.getValue()));
}
List<Map.Entry<String, Integer>> res = new ArrayList<>(h3.entrySet());
res.sort(Map.Entry.comparingByKey());
for (Map.Entry<String, Integer> entry : res) {
System.out.println(entry.getKey() + "," + entry.getValue());
}
}
}
Python:[此代码未进行大量数据的测试,仅供参考]
import sys
input = sys.stdin.read
from collections import defaultdict
def main():
data = input().splitlines()
n = int(data[0])
a = [""] * 5
h1 = defaultdict(int)
ses = set()
index = 1
for _ in range(n):
s = data[index]
index += 1
parts = s.split(',')
for i in range(len(parts)):
a[i] = parts[i]
ts = a[0] + a[1] + a[2]
if ts in ses:
continue
else:
ses.add(ts)
tt = int(a[3])
if tt < 0 or tt > 100:
continue
h1[(a[1], a[2])] += tt
m = int(data[index])
index += 1
h2 = {}
for _ in range(m):
s = data[index]
index += 1
parts = s.split(',')
for i in range(len(parts)):
a[i] = parts[i]
h2[a[0]] = int(a[1])
h3 = defaultdict(int)
for (client, factor), v in h1.items():
h3[client] += h2.get(factor, 0) * v
res = sorted(h3.items())
for k, v in res:
print(f"{k},{v}")
if __name__ == "__main__":
main()
第二题
题目:相似图片分类
小明想要处理一批图片,将相似的图片分类。他首先对图片的特征采样,得到图片之间的相似度,然后按照以下规则判断图片是否可以归为一类:
1)相似度>0表示两张图片相似,
2)如果A和B相似,B和C相似,但A和C不相似。那么认为A和C间接相似,可以把ABC归为一类,但不计算AC的相似度
3)如果A和所有其他图片都不相似,则A自己归为一类,相似度为0.给定一个大小为NxN的矩阵M存储任意两张图片的相似度,M[i][j]即为第i个图片和第j个图片的相似度,请按照"从大到小”的顺序返回每个相似类中所有图片的相似度之和。
输入描述
第一行一个数N,代表矩阵M中有N个图片,下面跟着N行,每行有N列数据,空格分隔(为了显示整弃,空格可能为多个) 代表N个图片之间的相似度。
约束:
1.0<N<=900
2.0<=M[i][j]<=100,输入保证M[i][i] =0,M[i][j]=M[j][i]
输出描述
每个相似类的相似度之和。格式为:一行数字,分隔符为1个空格。
样例输入
5
0 0 50 0 0
0 0 0 25 0
50 0 0 0 15
0 25 0 0 0
0 0 15 0 0
样例输出
65 25
参考题解
考察并查集,将相似度大于0的节点合并,用num数组储存分数,每次合并的时候累加分数,最后对不同集合类的分数排序输出就行。
C++:[此代码未进行大量数据的测试,仅供参考]
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 900 + 7;
int a[N][N];
int n, m, p[N], num[N];
int find(int x)
{
if(x != p[x]) p[x] = find(p[x]);
return p[x];
}
int main()
{
cin >> n;
for(int i = 0; i < n; i++) p[i] = i, num[i] = 0;
for(int i = 0; i < n; i ++)
{
for(int j = 0; j < n; j ++)
{
cin >> a[i][j];
}
}
for(int i = 0; i < n; i++)
{
for(int j = i; j < n; j ++)
{
if(a[i][j] > 0)
{
int px = find(i), py = find(j);
if(px != py)
{
p[px] = py;
num[py] += a[i][j] + num[px];
}
else num[py] += a[i][j];
}
}
}
vector<int> res;
for(int i = 0; i < n; i ++)
{
if(p[i] == i)
{
res.push_back(num[i]);
}
}
sort(res.begin(), res.end());
for(int i = res.size() - 1; i >= 0; i --)
{
if(i)
cout << res[i] << " ";
else cout << res[i];
}
return 0;
}
Java:[此代码未进行大量数据的测试,仅供参考]
import java.util.*;
public class Main {
static final int N = 900 + 7;
static int[][] a = new int[N][N];
static int[] p = new int[N], num = new int[N];
static int find(int x) {
if (x != p[x]) p[x] = find(p[x]);
return p[x];
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
for (int i = 0; i < n; i++) {
p[i] = i;
num[i] = 0;
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
a[i][j] = sc.nextInt();
}
}
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
if (a[i][j] > 0) {
int px = find(i), py = find(j);
if (px != py) {
p[px] = py;
num[py] += a[i][j] + num[px];
} else {
num[py] += a[i][j];
}
}
}
}
List<Integer> res = new ArrayList<>();
for (int i = 0; i < n; i++) {
if (p[i] == i) {
res.add(num[i]);
}
}
Collections.sort(res, Collections.reverseOrder());
for (int i = 0; i < res.size(); i++) {
if (i > 0) System.out.print(" ");
System.out.print(res.get(i));
}
}
}
Python:[此代码未进行大量数据的测试,仅供参考]
def find(p, x):
if x != p[x]:
p[x] = find(p, p[x])
return p[x]
def main():
import sys
input = sys.stdin.read
data = input().split()
index = 0
n = int(data[index])
index += 1
N = 900 + 7
a = [[0] * N for _ in range(N)]
p = [i for i in range(N)]
num = [0] * N
for i in range(n):
for j in range(n):
a[i][j] = int(data[index])
index += 1
for i in range(n):
for j in range(i, n):
if a[i][j] > 0:
px = find(p, i)
py = find(p, j)
if px != py:
p[px] = py
num[py] += a[i][j] + num[px]
else:
num[py] += a[i][j]
res = []
for i in range(n):
if p[i] == i:
res.append(num[i])
res.sort(reverse=True)
print(" ".join(map(str, res)))
if __name__ == "__main__":
main()
第三题
题目:网络保卫战
公有云的某个region内,N个网络节点组网情况可以使用一个n* n的矩阵matrix表示,在这个组网图中,matrix[i][j] = p 时,表示用户在编号为 i的节点访问编号为j的节点时,必须在 i节点上具有>=p 的权限等级(p=0时表示无法通过第i节点访问j节点),如果用户成功访问了j节点,那么它在j节点上的权限等级调整为 P。
exposed 为一个整数数组,表示暴露在公网上的网络节点的编号列表。某天扫描发现这批暴需在公网的节点存在被外部恶意攻击风险且该攻击会影响到可访问的其他节点,并可以持续传递进行攻击,被恶意攻击的节点从公网访问时,攻击者获得了ROOT 权限(权限等级为10,即最大值)。
小李是一名网络安全工程师,为了在有限的时间内尽可能的减少故障带来的损失,需要立即将某个节点从公网"下线"。
假设攻击结束时,被攻击过的节点数量为R,请帮小李计算出将哪个节点下线能使R尽可能小,如果答案有多个节点,返回索引最小的那个节点。
请注意:从公网“下线”的节点,不会受到来自公网的攻击,但仍然可能被“可访问”的其他节点传递攻击。
输入描述
输入的第一行是网络节点数量N
后续的N行,每行N个数字v,以空格分割,形成一个N*N的矩阵,表示网络节点组网的矩阵。
最后一行,输入 exposed 数组,表示暴露在公网上的网络节点的编号列表,数组元素不会重复。
输入范围说明:
2<=n<=24
0<=v<=10
0<=exposed[i]<=n-1
输出描述
输出在 exposed 数组中,计划"下线”的那个节点的编号。
样例输入
4
1 0 0 0
0 1 2 0
0 1 1 4
0 0 3 1
1 3
样例输出
3
参考题解
遍历每个暴露的节点,dfs搜索遍历能走到多少节点, 选择能到达节点数最多的点就是要下线的答案。
C++:[此代码未进行大量数据的测试,仅供参考]
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int n;
const int N = 30;
int a[N][N];
bool st[N];
int dfs(int id, int ra)
{
int num = 0, sm = 0;
for(int i = 0; i < n; i ++)
{
if(id == i || !a[id][i]) continue;
if(ra >= a[id][i])
{
if(st[i]) continue;
st[i] = true;
num += dfs(i, a[id][i]);
st[i] = false;
}
}
return num + 1;
}
int main()
{
cin >> n;
for(int i = 0; i < n; i ++)
for(int j = 0; j < n; j ++)
cin >> a[i][j];
int x;
int res = -1, ans = 0;
while(cin >> x)
{
for(int i = 0; i < n; i ++)
{
if(x == i) continue;
st[x] = true;
int t = dfs(x, 10);
st[x] = false;
if(t > ans)
{
ans = t;
res = x;
}
}
}
cout << res;
return 0;
}
Java:[此代码未进行大量数据的测试,仅供参考]
import java.util.Scanner;
public class Main {
static final int N = 30;
static int[][] a = new int[N][N];
static boolean[] st = new boolean[N];
static int n;
static int dfs(int id, int ra) {
int num = 0;
for (int i = 0; i < n; i++) {
if (id == i || a[id][i] == 0) continue;
if (ra >= a[id][i]) {
if (st[i]) continue;
st[i] = true;
num += dfs(i, a[id][i]);
st[i] = false;
}
}
return num + 1;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
a[i][j] = sc.nextInt();
}
}
int res = -1, ans = 0;
while (sc.hasNextInt()) {
int x = sc.nextInt();
for (int i = 0; i < n; i++) {
if (x == i) continue;
st[x] = true;
int t = dfs(x, 10);
st[x] = false;
if (t > ans) {
ans = t;
res = x;
}
}
}
System.out.println(res);
}
}
Python:[此代码未进行大量数据的测试,仅供参考]
def dfs(id, ra):
num = 0
for i in range(n):
if id == i or a[id][i] == 0:
continue
if ra >= a[id][i]:
if st[i]:
continue
st[i] = True
num += dfs(i, a[id][i])
st[i] = False
return num + 1
import sys
input = sys.stdin.read
data = input().split()
index = 0
n = int(data[index])
index += 1
N = 30
a = [[0] * N for _ in range(N)]
st = [False] * N
for i in range(n):
for j in range(n):
a[i][j] = int(data[index])
index += 1
res = -1
ans = 0
while index < len(data):
x = int(data[index])
index += 1
for i in range(n):
if x == i:
continue
st[x] = True
t = dfs(x, 10)
st[x] = False
if t > ans:
ans = t
res = x
print(res)
#华为实习##华为笔试##华为#HW打怪升级指南,包含春招秋招实习的打怪之路,持续更新多种语言版本,一起学习一起进步
