赞
踩
LYA 是一家云服务提供商,她需要为客户提供云服务计费功能。现在,她有一份包含多条计费日志的文件,每条日志包含时间戳、客户标识、计费因子和计费时长四个字段。此外,她还有一份计费因子的单价列表。
LYA 需要编写一个程序,根据计费日志和计费因子单价列表,计算每个客户的话单总费用。需要注意的是,如果同一客户在相同时间戳上报了多条相同计费因子的日志,只能计费一次,并且选择先上报的日志进行计费。
第一行包含一个正整数 n n n,表示计费日志的条数, 1 ≤ n ≤ 1000 1 \leq n \leq 1000 1≤n≤1000。
接下来的 n n n 行,每行包含四个字段,分别表示时间戳(长度为 10 10 10 的数字字符串)、客户标识(长度为 1 ∼ 16 1 \sim 16 1∼16 的字符串)、计费因子(长度为 1 ∼ 16 1 \sim 16 1∼16 的字符串)和计费时长(范围为 0 ∼ 100 0 \sim 100 0∼100 的整数),字段之间用逗号分隔。如果计费因子在单价列表中查不到,则认为其单价为 0 0 0;如果计费时长不在 0 ∼ 100 0 \sim 100 0∼100 的范围内,则认为计费时长为 0 0 0。
接下来一行包含一个正整数 m m m,表示计费因子的数量, 1 ≤ m ≤ 100 1 \leq m \leq 100 1≤m≤100。
最后的 m m m 行,每行包含两个字段,分别表示计费因子(长度为 1 ∼ 16 1 \sim 16 1∼16 的字符串)和单价(范围为 1 ∼ 100 1 \sim 100 1∼100 的整数),字段之间用逗号分隔。
输出每个客户的话单总费用,每行包含两个字段,分别表示客户标识和话单费用,字段之间用逗号分隔。输出按照客户标识的字典序升序排列。
5
1627845600,client1,factorA,10
1627845605,client2,factorB,15
1627845610,client1,factorA,5
1627845615,client1,factorB,8
1627845620,client2,factorB,20
2
factorA,5
factorB,7
client1,131
client2,245
本题可以用DFS求解。基本思路如下:
#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; }
LYA 是一位图像处理工程师,她需要设计一个算法来对一批图片进行分类。首先,她对每张图片提取特征,并计算任意两张图片之间的相似度。然后,根据以下规则将图片归类:
给定一个大小为 N × N N \times N N×N 的矩阵 M M M,其中 M [ i ] [ j ] M[i][j] M[i][j] 表示第 i i i 张图片和第 j j j 张图片的相似度,请按照从大到小的顺序返回每个相似类中所有图片的相似度之和。
第一行包含一个正整数 N N N( 1 ≤ N ≤ 900 1 \leq N \leq 900 1≤N≤900),表示矩阵 M M M 中图片的数量。
接下来的 N N N 行,每行包含 N N N 个用空格分隔的非负整数,表示矩阵 M M M。其中, 0 ≤ M [ i ] [ j ] ≤ 100 0 \leq M[i][j] \leq 100 0≤M[i][j]≤100,并且保证 M [ i ] [ j ] = M [ j ] [ i ] M[i][j] = M[j][i] M[i][j]=M[j][i]。
注意:输入的矩阵元素之间的分隔符可能是一个或多个连续的空格。
输出每个相似类的相似度之和,按照从大到小的顺序输出。每个数占一行,相邻两个数之间用一个空格分隔。
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
首先,提取每张图片的特征并计算图片间的相似度矩阵。然后按照给定的规则对图片进行分类,并计算每个相似类中所有图片的相似度之和。
为了解决这个问题,我们可以采用深度优先搜索,并查集等方法来处理相似类的合并,然后计算相似度之和。使用并查集将相似的图片进行合并。接着计算每个相似类中所有图片的相似度之和,并按照从大到小的顺序输出。
#include <iostream> #include <vector> #include <algorithm> using namespace std; class UnionFind { private: vector<int> parent; vector<int> rank; public: UnionFind(int n) { parent.resize(n); rank.resize(n); for (int i = 0; i < n; ++i) { parent[i] = i; rank[i] = 0; } } int find(int x) { if (x != parent[x]) { parent[x] = find(parent[x]); } return parent[x]; } void merge(int x, int y) { int rootX = find(x); int rootY = find(y); if (rootX != rootY) { if (rank[rootX] < rank[rootY]) { parent[rootX] = rootY; } else if (rank[rootX] > rank[rootY]) { parent[rootY] = rootX; } else { parent[rootY] = rootX; rank[rootX]++; } } } }; int main() { int N; cin >> N; vector<vector<int>> M(N, vector<int>(N)); for (int i = 0; i < N; ++i) { for (int j = 0; j < N; ++j) { cin >> M[i][j]; } } UnionFind uf(N); for (int i = 0; i < N; ++i) { for (int j = i + 1; j < N; ++j) { if (M[i][j] > 0) { uf.merge(i, j); } } } vector<int> sum(N, 0); for (int i = 0; i < N; ++i) { sum[uf.find(i)] += accumulate(M[i].begin(), M[i].end(), 0); } sort(sum.rbegin(), sum.rend()); for (int i = 0; i < N; ++i) { if (sum[i] > 0) { cout << sum[i] << endl; } } return 0; }
K小姐是一名网络安全工程师,她负责维护一个由 N N N 个节点组成的内部网络。这个网络的连通性可以用一个 N × N N\times N N×N 的矩阵 m a t r i x matrix matrix 来表示,其中 m a t r i x [ i ] [ j ] = p matrix[i][j]=p matrix[i][j]=p 表示从节点 i i i 到节点 j j j 需要的最低权限等级为 p p p( p = 0 p=0 p=0 表示不连通)。如果成功访问了节点 j j j,则该节点的权限等级会被调整为 p p p。
某天,K小姐发现有一些节点暴露在了公网上,存在被外部攻击的风险。暴露节点的编号保存在数组 e x p o s e d exposed exposed 中。如果攻击者从公网入侵了某个暴露节点,则该节点的权限等级会变为最高等级 10 10 10。同时,入侵可以在网络内部传播,只要满足权限等级的要求即可。
为了尽快控制损失,K小姐决定立即将某个暴露节点从公网断开。她希望你能帮忙计算,断开哪个节点能够使最终被入侵的节点数量最少。如果有多个答案,则输出编号最小的节点。
第一行包含一个正整数 N N N,表示网络中节点的数量。
接下来 N N N 行,每行包含 N N N 个空格分隔的整数,表示矩阵 m a t r i x matrix matrix。
最后一行包含若干个空格分隔的整数,表示数组 e x p o s e d exposed exposed。
输出一个整数,表示应该断开的节点编号。
4
1 0 0 0
0 1 2 0
0 1 1 4
0 0 3 1
1 3
3
这个问题可以通过模拟攻击来解决。首先,我们需要遍历每个可能的断开的节点,然后模拟从公网入侵并在网络内部传播的过程,最终统计每个节点被入侵的次数。最后,选择使得被入侵节点数量最少的节点进行断开。
#include <iostream> #include <vector> #include <climits> using namespace std; int simulateAttack(vector<vector<int>>& matrix, vector<int>& exposed, int disconnected_node) { int n = matrix.size(); vector<bool> visited(n, false); vector<int> permissions(n, INT_MAX); for (int i = 0; i < n; ++i) { matrix[i][disconnected_node] = 0; } int exposed_count = 0; for (int ex_node : exposed) { if (!visited[ex_node]) { exposed_count++; visited[ex_node] = true; permissions[ex_node] = 10; for (int i = 0; i < n; ++i) { if (matrix[ex_node][i] != 0 && matrix[ex_node][i] <= permissions[ex_node]) { permissions[i] = min(permissions[i], matrix[ex_node][i]); } } } } for (int i = 0; i < n; ++i) { if (!visited[i]) { for (int ex_node : exposed) { if (matrix[i][ex_node] != 0 && matrix[i][ex_node] <= permissions[ex_node]) { visited[i] = true; exposed_count++; break; } } } } return exposed_count; } int main() { int n; cin >> n; // Read matrix vector<vector<int>> matrix(n, vector<int>(n)); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { cin >> matrix[i][j]; } } // Read exposed nodes vector<int> exposed; int node; while (cin >> node) { exposed.push_back(node); } // Find the node to disconnect int min_exposed_count = INT_MAX; int disconnect_node = -1; for (int i = 0; i < n; ++i) { int exposed_count = simulateAttack(matrix, exposed, i); if (exposed_count < min_exposed_count) { min_exposed_count = exposed_count; disconnect_node = i; } } cout << disconnect_node << endl; return 0; }
整理试题不易,你的关注是我更新的最大动力!关注博主 带你看更多面试及竞赛试题和实用算法。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。