三题120分钟,分值=100+200+300。需要自己处理输入。
华为是谁?
华为是全球领先的信息与通信技术( ICT)解决方案供应商,专注于 ICT 领域,坚持稳
健经营、持续创新、开放合作,在电信运营商、企业、终端和云计算等领域构筑了端到端
的解决方案优势,为运营商客户、企业客户和消费者提供有竞争力的 ICT 解决方案、产品
和服务,并致力于使能未来信息社会、 构建更美好的全联接世界。目前,华为有 17 万多
名员工,业务遍及全球 170 多个国家和地区,服务全世界三分之一以上的人口。
我们为世界带来了什么?
为客户创造价值。华为和运营商一起,在全球建设了 1,500 多张网络,帮助世界超过
三分之一的人口实现联接。华为和企业客户一起,以开放的云计算和敏捷的企业网络,助
力平安城市、金融、交通、能源等领域实现高效运营和敏捷创新。华为智能终端和智能手
机,正在帮助人们享受高品质的数字工作、生活和娱乐体验。
推动行业良性发展。华为主张开放、合作、共赢,与上下游合作伙伴及友商合作创新、
扩大产业价值,形成健康良性的产业生态系统。华为加入 300 多个标准组织、产业联盟和
开源社区,累计提案 4.3 万篇。我们面向云计算、NFV/SDN、5G 等新兴热点领域,与产业
伙伴分工协作,推动行业持续良性发展。
促进经济增长。华为为所在国家不仅带来直接的纳税、就业促进、产业链带动效应,
更重要的是通过创新的 ICT 解决方案打造数字化引擎,推动各行各业数字化转型,促进经
济增长,提升人们的生活质量与福祉。
促进社会可持续发展。作为负责任的企业公民,华为致力于消除全球数字鸿沟;在西
非埃博拉疫区、日本海啸核泄漏、中国汶川大地震等重大灾难现场,我们深知灾难面前通
信的重要性,我们选择了坚守;我们在全球开展 “未来种子”项目,为各国青年学生提
供来中国培训实习的机会。
- 最大绝对值之差
树。找出一个节点,把这个节点与parent隔断,成为新的树的root。目标是最大化两颗树的差值。返回应该割裂开的节点,如果出现平局,返回索引较小的。
第一行输入是n,表示一共多少节点。第二行是所有节点的值。之后是节点的关系,【parent,child】。
input:
4
4 9 -7 -8
0 1
0 3
1 2
output: 3
注意,在关系中左child一定会比右child先出现。
public class Main {
static int largestGap = 0;
static int res = 100000;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
Node[] nodes = new Node[n];
boolean[] notRoot = new boolean[n];
for (int i = 0; i < n; i++) {
int v = sc.nextInt();
nodes[i] = new Node(i, v);
}
while (sc.hasNextInt()) {
int p = sc.nextInt();
int c = sc.nextInt();
Node par = nodes[p];
Node child = nodes[c];
notRoot[c] = true;
if (par.left == null)
par.left = child;
else
par.right = child;
}
Node root = null;
for (int i = 0; i < n; i++) {
if (!notRoot[i]) {
root = nodes[i];
break;
}
}
subtreeSum(root);
findGap(root, 0);
System.out.println(res);
}
private static void findGap(Node root, int parVal) {
if (root == null)
return;
int left = 0;
int right = 0;
// System.out.printf("findgap(), root.id=%d, largestGap=%d, res=%d\n", root.idx, largestGap,
// res);
if (root.left != null) {
left = root.left.sum;
int leftgap = Math.abs(root.sum + parVal - 2 * left);
// System.out.printf("left=%d, leftgap=%d\n", left, leftgap);
if (leftgap > largestGap) {
largestGap = leftgap;
res = root.left.idx;
} else if (leftgap == largestGap && root.left.idx < res) {
res = root.left.idx;
}
}
if (root.right != null) {
right = root.right.sum;
int rightgap = Math.abs(root.sum + parVal - 2 * right);
// System.out.printf("right=%d, rightgap=%d\n", right, rightgap);
if (rightgap > largestGap) {
largestGap = rightgap;
res = root.right.idx;
} else if (rightgap == largestGap && root.right.idx < res) {
res = root.right.idx;
}
}
// System.out.printf("largestGap=%d, res=%d\n", largestGap, res);
findGap(root.left, parVal + root.val + right);
findGap(root.right, parVal + root.val + left);
}
private static int subtreeSum(Node root) {
if (root == null)
return 0;
int left = subtreeSum(root.left);
int right = subtreeSum(root.right);
int s = left + right + root.val;
root.sum = s;
return s;
}
}
class Node {
int idx;
int val;
int sum;
Node left;
Node right;
public Node(int i, int v) {
idx = i;
val = v;
sum = 0;
left = null;
right = null;
}
}
- 梅花桩
格子表示可跳跃的步数。第一行是m,n,表示棋盘的大小。求到达最右下角最少的步数。如果无法到达,返回-1。
public class Main {
public static void main(String[] args) {
final int INF = 100*100*10+1;
Scanner sc = new Scanner(System.in);
String[] input = sc.nextLine().split(",");
int m = Integer.parseInt(input[0]);
if (m <= 0) {
System.out.println("-1");
return;
}
int n = Integer.parseInt(input[1]);
if (n <= 0) {
System.out.println("-1");
return;
}
int[][] grid = new int[m][n];
int[][] dp = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
grid[i][j] = sc.nextInt();
dp[i][j] = INF;
}
}
dp[0][0] = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == 0) continue;
// jump to right
for (int k = 1; k <= grid[i][j]; k++) {
if (j+k >= n) break;
if (grid[i][j+k] == 0) continue;
dp[i][j+k] = Math.min(dp[i][j+k], dp[i][j]+1);
}
// jump to bottom
for (int k = 1; k <= grid[i][j]; k++) {
if (i+k >= m) break;
if (grid[i+k][j] == 0) continue;
dp[i+k][j] = Math.min(dp[i+k][j], dp[i][j]+1);
}
}
}
if (dp[m-1][n-1] >= INF) {
System.out.println("-1");
return;
}
System.out.println(dp[m-1][n-1]);
}
private static void print2d(int[][] arr) {
int m = arr.length;
for (int i = 0; i < m; i++)
System.out.println(Arrays.toString(arr[i]));
System.out.println();
}
}
- 最短编译时间
只过5%的test case,时间来不及。
不同项目需要不同的依赖。第一行是目标项目。之后每一行表示一个项目所依赖的项目和编译时间,格式为[项目名称,编译时间,*依赖项目]。依赖的项目必须要先做完。
input:
module3
module1,10
module2,5
module3,10,module1,module2
output: 20
input:
module2
module2,10,module1
output: -1
input:
module2
module2,10,module1
module1,10,module2
output: -1
public class Main {
static boolean valid = true;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String goal = sc.nextLine().trim();
Map<String, Integer> duration = new HashMap();
Map<String, Set<String>> prereqs = new HashMap();
while (sc.hasNextLine()) {
String[] input = sc.nextLine().split(",");
int d = Integer.parseInt(input[1]);
duration.put(input[0], d);
Set<String> pre = new HashSet();
for (int i = 2; i < input.length; i++)
pre.add(input[i]);
prereqs.put(input[0], pre);
}
int res = getTime(goal, duration, prereqs, new HashSet());
if (!valid)
System.out.println("-1");
else
System.out.println(res);
}
private static int getTime(String cur, Map<String, Integer> duration, Map<String, Set<String>> prereqs, Set<String> seen) {
if (!valid) return -1;
if (!prereqs.containsKey(cur) || seen.contains(cur)) {
valid = false;
return -1;
}
seen.add(cur);
Set<String> pres = prereqs.get(cur);
int t = duration.get(cur);
int front = 0;
for (String pre: pres) {
front = Math.max(front, getTime(pre, duration, prereqs, seen));
}
// 这行是考完之后才加的,忘记backtrack
seen.remove(cur);
return t+front;
}
}
如果不加上最后有一行代码(有注释那行),假设两个模块同时依赖一个模块,会出问题。可惜当时没有想到这种情况,测试平台所有测试用例是用户不可见的(只能自测)。
特别感谢Oscar哥帮忙debug。