对华为文化的了解

华为的企业文化可以用几个关键词来概括:奋斗、客户至上、团队合作和自我批判。以下是一些具体的特点:

  1. 奋斗者文化:华为一直强调“奋斗者为本”,这不仅仅是对员工的期望,也体现在公司对个人的奖励制度上。公司认为,只有通过努力和奋斗,才能在竞争中脱颖而出,创造更大的价值。因此,华为推崇拼搏精神,鼓励员工不断进步。
  2. 客户至上:华为在文化中一直强调“以客户为中心”。这意味着华为关注客户的需求和期望,致力于提供最优质的产品和服务。公司倡导通过创新和精益求精来满足客户的需求。
  3. 自我批判和持续改进:华为的领导层,尤其是创始人任正非,推崇自我批判的精神。公司鼓励员工、管理层定期反思并查找自己的不足,不断改进,不满足于现状。任正非曾多次提到,华为的成功不仅仅是外部环境使然,更重要的是公司能够在内部自我调整、避免固守错误的做法。
  4. 全球化与本地化:华为从创立伊始就立足于全球化发展,强调跨文化的交流与融合。公司在全球范围内设有研发中心,注重本地化的产品设计与服务。
  5. 高度的责任感:华为还推崇高度的社会责任感。任正非曾提到,华为不仅仅要在商业上成功,还要在社会和文化层面贡献自己的力量。华为也积极参与公益活动,特别是在教育和环保领域。
  6. 自由与责任并重:华为推崇自由的工作氛围,鼓励员工在公司内部开展创新和自由探索,同时也强调员工要对自己的工作结果负责。

这些文化元素帮助华为成为了全球领先的通信技术和设备供应商,也为其在激烈的市场竞争中积累了强大的竞争力。当然,华为的文化也因为其高强度的工作压力和某些管理方式而在外界有所争议。

Q1

Java ACM模式解题
有一个定时器系统:

  1. 该系统精度为1刻度、可容纳n个超时任务;
  2. 每个人屋里包含该任务超时时刻t(当系统时钟到达t时,该任务开始执行),t为正整数;
  3. 同一时刻超时的任务按照加入系统的先后顺序依次执行超时任务;
  4. 当定时器中任务不足n个时候,可以直接添加新任务;
  5. 当定时器中任务数达到n个时候,假定待添加任务的超时时刻为ti,系统中最后执行的任务的超时时刻为tj,如果ti>tj,则丢弃待添加的任务,否则丢弃系统中最晚执行的超时任务,并将待添加任务加入系统中。

现在给定定时器容量n,短时间内(不到1刻度)依次向该系统添加m个定时任务tasks,假定当前时钟为0时刻,即添加的任务都是未超时任务,且都是一次性定时任务。

输出该定时器系统中最后超时的任务索引号,即:当前task在tasks中的下标(下标从0开始),如果多个任务同时超时,则输出最大的索引号。

输入描述
第一行 容量n, 1<=n<=1000
第二行 任务个数m, 1<=m<=1000000
第三行 m个正整数,表示任务超时时刻,1<=ti<=100000

输出描述
输出最后超时的任务索引号

样例输入
2
12
1 2 3 4 6 19 20 21 22 23 24 1
样例输出
11
说明:
容量为2,最终定时器只会有两个任务,分别为1(索引为0), 1(索引为11),这两个任务同时超时,返回更大的任务索引号为11

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import java.util.*;

public class Q1 {
// 内部类,用于表示任务和其超时时刻的索引
static class Task {
int time;
int index;

Task(int time, int index) {
this.time = time;
this.index = index;
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);

// 输入
int n = sc.nextInt(); // 定时器容量
int m = sc.nextInt(); // 任务数量
int[] tasks = new int[m]; // 超时时刻

for (int i = 0; i < m; i++) {
tasks[i] = sc.nextInt();
}

// 定时器任务管理:队列保存超时时刻和任务的索引
Deque<Task> timer = new LinkedList<>();

// 记录队列中的任务
for (int i = 0; i < m; i++) {
int time = tasks[i];

// 如果定时器未满,直接添加任务
if (timer.size() < n) {
timer.offer(new Task(time, i));
} else {
// 如果定时器已满,查看任务超时刻是否符合条件
Task lastTask = timer.peekLast(); // 获取队列中最晚的超时任务
if (time <= lastTask.time) {
timer.pollLast(); // 移除最晚超时任务
timer.offer(new Task(time, i)); // 添加新任务
}
}
}

// 输出队列中最后一个超时任务的索引
// int lastTaskIndex = -1;
// while (!timer.isEmpty()) {
// lastTaskIndex = timer.poll().index;
// }

System.out.println(timer.peekLast().index);
}
}

Q2

Java ACM模式解题
数据中心摆放M排N列机柜,现需要在每排选择一个机柜安装监控器来监视本排机柜的用电量,由于监控器安装位置太近的话会相互干扰,安装时候需要满足条件:
安装监控器的机柜不能在同一排或者同一列,并且不能在同一斜线上(45°或者135°的正斜线)。请问一共有多少种安装监控器的方案?

输入描述
机柜的行数M和列数N(1<=M,N<15)

输出描述
输出一行一个整数表示方案数,如果没有方案则输出0

样例输入
2 3
样例输出
2
说明
有两种安装方案
1 0 0
0 0 1

0 0 1
1 0 0

其中,1表示安装监控器的机柜,0表示未安装监控器的机柜

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
public class Q2 {
static int M, N;
static int count = 0;

// 使用数组记录哪些列、主对角线、副对角线已经被占用
static boolean[] Cols;
static boolean[] Line1; // 左上到右下
static boolean[] Line2; // 右上到左下

public static void main(String[] args) {
// 读取输入
java.util.Scanner sc = new java.util.Scanner(System.in);
M = sc.nextInt();
N = sc.nextInt();

// 初始化数组
Cols = new boolean[N]; // 标记每一列是否已使用
Line1 = new boolean[M + N - 1]; // 标记每条主对角线是否已使用
Line2 = new boolean[M + N - 1]; // 标记每条副对角线是否已使用

// 开始回溯
backtrack(0);

// 输出结果
System.out.println(count);
}

// 回溯函数,尝试在第 row 行安装监控器
static void backtrack(int row) {
if (row == M) {
// 已经处理了所有的行,说明找到了一种合法的方案
count++;
return;
}

// 遍历当前行的所有列
for (int col = 0; col < N; col++) {
// 检查当前列和对角线是否已被占用
if (Cols[col] || Line1[row - col + N - 1] || Line2[row + col]) {
continue; // 如果当前选择不合法,跳过
}

// 标记当前列和对角线为已使用
Cols[col] = true;
Line1[row - col + N - 1] = true;
Line2[row + col] = true;

// 递归尝试放置下一个行的监控器
backtrack(row + 1);

// 回溯,撤销选择
Cols[col] = false;
Line1[row - col + N - 1] = false;
Line2[row + col] = false;
}
}
}

Q3

Java ACM模式解题
小明在一个足球场上踢球,他需要绕过障碍物把球踢到球门里。

足球场用M*M的正方形网格表示,其中每个元素可以是下面的值之一:
X:表示小明,只要他在空地里面,就可以上下左右四个方向移动。
0:表示空地,小明可以自由移动。
1:表示障碍物,意味着不能通行,可能有多个。
B:表示球,小明需要把球踢到球门,只能有一个。
G:表示球门,小明需要把球踢到这里,只能有一个。

初始时候小明和球可能不相邻,他需要走到球的位置才能开始踢球;当移动到球边(相邻格子)后,继续向着球的方向移动,球会被踢到同方向相邻格的位置,即:球移动方向与小明移动方向相同,一次移动一格。
注:如果球移动前方会碰到障碍物或者边界,那么此次踢球无效,小明和球的位置均不变。

小明需要持续移动,直到球被踢进球门,返回小明踢球的最小次数,如果无法踢进,返回-1。
注:足球的每一次移动算作一次踢球,小明自己移动不算踢球。

输入描述:
第一行一个整数M,表示网格的大小。5<=M<=20
接下来M行,每行M个字符,表示网格的元素。仅包含X,0,1,B,G这五种字符,且保证有且仅有一个X,一个B,一个G。

输出描述:
输出一个整数,表示小明踢球的最小次数,如果无法踢进,返回-1。

样例输入
5
0 0 0 0 0
0 0 0 0 G
0 0 B 0 0
X 1 0 0 0
0 0 0 0 0
样例输出
3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import java.util.*;

public class Q3 {
// 定义四个方向的移动(上下左右)
static int[] dx = {-1, 1, 0, 0};
static int[] dy = {0, 0, -1, 1};

public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);

// 读取输入
int M = scanner.nextInt();
scanner.nextLine(); // 读取换行符

char[][] grid = new char[M][M];
int XX = -1, XY = -1, BX = -1, BY = -1, GX = -1, GY = -1;

for (int i = 0; i < M; i++) {
String[] line = scanner.nextLine().split(" ");
for (int j = 0; j < M; j++) {
grid[i][j] = line[j].charAt(0);
if (grid[i][j] == 'X') {
XX = i;
XY = j;
} else if (grid[i][j] == 'B') {
BX = i;
BY = j;
} else if (grid[i][j] == 'G') {
GX = i;
GY = j;
}
}
}

// 使用BFS搜索
int result = bfs(grid, M, XX, XY, BX, BY, GX, GY);
System.out.println(result);
}

static int bfs(char[][] grid, int M, int XX, int XY, int BX, int BY, int GX, int GY) {
// 队列保存的是 (小明x, 小明y, 球x, 球y, 踢球次数)
Queue<int[]> queue = new LinkedList<>();
Set<String> visited = new HashSet<>();

// 初始状态加入队列
queue.offer(new int[] {XX, XY, BX, BY, 0});
visited.add(XX + "," + XY + "," + BX + "," + BY);

while (!queue.isEmpty()) {
int[] state = queue.poll();
int xx = state[0], xy = state[1], bx = state[2], by = state[3], kicks = state[4];

// 如果球已经到达球门
if (bx == GX && by == GY) {
return kicks;
}

// 小明可以向四个方向移动
for (int i = 0; i < 4; i++) {
int newX = xx + dx[i], newY = xy + dy[i];

// 判断小明的移动是否有效
if (newX >= 0 && newX < M && newY >= 0 && newY < M && grid[newX][newY] != '1') {
// 判断是否与球相邻
if (Math.abs(newX - bx) + Math.abs(newY - by) == 1) {
// 小明与球相邻,开始踢球
int newBX = bx + dx[i], newBY = by + dy[i];

// 判断球是否能被踢动
if (newBX >= 0 && newBX < M && newBY >= 0 && newBY < M && grid[newBX][newBY] != '1') {
// 球能被踢动
if (!visited.contains(newX + "," + newY + "," + newBX + "," + newBY)) {
visited.add(newX + "," + newY + "," + newBX + "," + newBY);
queue.offer(new int[] {newX, newY, newBX, newBY, kicks + 1});
}
}
} else {
// 小明移动,不是踢球
if (!visited.contains(newX + "," + newY + "," + bx + "," + by)) {
visited.add(newX + "," + newY + "," + bx + "," + by);
queue.offer(new int[] {newX, newY, bx, by, kicks});
}
}
}
}
}

// 如果无法到达球门
return -1;
}
}