当前位置:   article > 正文

华为机考真题_丢失报文的位置

丢失报文的位置

1、丢失报文的位置

某通信系统持续向外发送报文,使用数组 nums 保存 n个最近发送的报文,用于在报文未达到对端的情况下重发。报文使用序号 sn 表示,序号 sn 按照报文发送顺序从小到大排序,相邻报文 sn 不完全连续且有可能相同。报文使用循环覆盖的方式保存,即 nums 数组填满后,从头开始保存新的报文。假设需要重发序号为 sn 的报文。请找出序号为 sn的报文在数组中的开始位置和结束位置。

输入

第一行输入:数组 nums 的大小 n,取值范围 [0,10000]。

第二行输入:数组中的所有报文的序号 sn,sn 取值范围 [0,100000]。

第三行输入:需要重发的报文序号 sn,取值范围 [0,100000]。

输出

start end

说明:start 和 end 代表需要重发的报文序号 sn 在数组中的起始下标和结束下标。

样例

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
输入:
7
0 0 1 2 2 5 6
1

输出:
2 2

提示:
nums数组大小为7。
保存了7个报文,sn分别是0 0 1 2 2 5 6。
sn为1的报文在数组中仅有1个,下标是2,因此输出2 2。

输入:
7
0 0 1 2 2 5 6
2

输出:
3 4

提示:
nums数组大小为7。
保存了7个报文,sn分别是0 0 1 2 2 5 6。
sn为2的报文在数组中有2个,下标分别是3,4,因此输出3 4。

输入:
7
4 4 7 8 2 3 4
4

输出:
6 1

提示:
nums数组大小为7。
保存了7个报文,sn分别是4 4 7 8 2 3 4。
sn为4的报文在数组中有3个,下标分别是0,1,6,说明数组存在记录满了从头开始记录的情况,输出6 1。

输入:
7
4 4 7 8 2 3 4
6

输出:
-1 -1

提示:
nums数组大小为7。
保存了7个报文,sn分别是4 4 7 8 2 3 4。
数组中不存在sn为6的报文,因此输出-1 -1。

输入:
5
5 5 5 5 5
5

输出:
0 4

提示:
nums数组大小为5
保存了5个报文,sn分别是5 5 5 5 5
数组中所有报文sn都是5,这种情况下认为0是start,4是end,输出0 4。

思路

在本题中给定了保存的报文的需序号,这些序号是由发送顺序决定的,我们找到这段数组中最小的一个序号,然后从他开始遍历,标记开始的位置和结束的位置即可

代码

  1. import java.util.Scanner;
  2. public class test {
  3. public static void main(String[] args) {
  4. Scanner scanner = new Scanner(System.in);
  5. int n = scanner.nextInt();
  6. int[] a = new int[n];
  7. for (int i = 0; i < n; i++) {
  8. a[i] = scanner.nextInt();
  9. }
  10. int x = scanner.nextInt();
  11. int p = minElementIndex(a);
  12. int l = -1, r = -1;
  13. for (int i = 0; i < n; i++) {
  14. int q = (p + i) % n;
  15. if (a[q] == x) {
  16. if (l == -1) {
  17. l = q;
  18. }
  19. r = q;
  20. }
  21. }
  22. System.out.println(l + " " + r);
  23. }
  24. public static int minElementIndex(int[] arr) {
  25. int minIndex = 0;
  26. for (int i = 1; i < arr.length; i++) {
  27. if (arr[i] < arr[minIndex]) {
  28. minIndex = i;
  29. }
  30. }
  31. return minIndex;
  32. }
  33. }

2、快速传球

班级组织传球活动,男女同学随机排成 m 行 n 列队伍,第一列中的任意一个男同学都可以作为传球的起点,要求最终将球传到最后一列的任意一个男同学手里,求所有能够完成任务的传球路线中的最优路线(传球次数最少的路线)的传球次数。传球规则:

  1. 男同学只能将球传给男同学,不能传给女同学。
  2. 球只能传给身边前后左右相邻的同学。
  3. 如果游戏不能完成,返回 - 1.

说明:

  1. 传球次数最少的路线为最优路线。
  2. 最优路线可能不唯一,不同最优路线都为最少传球次数。

输入

班级同学随机排成的 m 行 n 列队伍,1 代表男同学,0 代表女同学。

输入第一行包含两个用空格分开的整数 m(m∈[1,30]) 和 n(n∈[1,30]),表示 m 行 n 列的队伍,接下来是 m 行每行包含 n 个用空格分开的整数 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
输入:
4 4
1 1 1 0
1 1 1 0
0 0 1 0
0 1 1 1

输出:
5

提示:
  图一            图二             图三
. . . 0         . . 1 0         1 1 1 0
1 1 . 0         1 . . 0         . . . 0
0 0 . 0         0 0 . 0         0 0 . 0
0 1 . .         0 1 . .         0 1 . .
图一传球路线需要传球6次。
图二传球路线需要传球6次。
图三传球路线需要传球5次,传球次数最少,为最优传球路线。

输入:
3 4
1 0 1 1
1 1 0 0
0 0 1 0

输出:
-1

提示:
选择第1行第1列的男同学作为起点,无法实现按规则将球到最后一列男同学手里。
选择第2行第1列的男同学作为起点,无法实现按规则将球到最后一列男同学手里。

解答

解答

声明一个d[][]去计算和存储到达最后一列男生的步数,d[][]同时也起到了记录该点位是否被访问的作用

在初始化阶段将第一列男生入队列,实现多元的bfs遍历。

最终打印最后一列所有男生中d[][]最小的那个值

代码

  1. import java.util.LinkedList;
  2. import java.util.Queue;
  3. import java.util.Scanner;
  4. public class test {
  5. static final int N = 35;
  6. static final int[] dx = {0,0,1,-1};
  7. static final int[] dy = {1,-1,0,0};
  8. public static void main(String[] args) {
  9. Scanner in = new Scanner(System.in);
  10. int n = in.nextInt();
  11. int m = in.nextInt();
  12. int[][] s = new int[N][N]; // 记录地图
  13. int[][] d = new int[N][N]; // 计算到达最后一列男生的最小步
  14. for(int i = 1;i<=n;i++){
  15. for (int j = 1;j<=m;j++ ){
  16. s[i][j] = in.nextInt();
  17. d[i][j] = -1;
  18. }
  19. }
  20. Queue<int []> q = new LinkedList<>();
  21. for(int i=1;i<=n;i++){ // 初始化第一列,将第一列男生入队列
  22. if (s[i][1] == 1){
  23. d[i][1] = 0;
  24. q.offer(new int[]{i,1});
  25. }
  26. }
  27. while (!q.isEmpty()){ // bfs搜索
  28. int[] front = q.poll();
  29. int sx = front[0];
  30. int sy = front[1];
  31. for(int i=0;i<4;i++){
  32. int x = sx+dx[i];
  33. int y = sy+dy[i];
  34. if((x < 1) || (y < 1) || (x > n) || (y > m) || d[x][y]!=-1 || s[x][y]==0){
  35. continue;
  36. }
  37. d[x][y] = d[sx][sy]+1;
  38. q.offer(new int[]{x,y});
  39. }
  40. }
  41. int ans = Integer.MAX_VALUE;
  42. for (int i = 1; i<=n;i++){
  43. if(s[i][m] == 1){
  44. ans = Math.min(ans,d[i][n]);
  45. }
  46. }
  47. if(ans == Integer.MAX_VALUE){
  48. ans = -1;
  49. }
  50. System.out.println(ans);
  51. }
  52. }

3、简易计算器

设计一款计算器软件,支持以下功能:

1支持 let 关键字。

2支持通过 let 赋值表达式定义变量并初始化。

例如:

1
2
let var1 = 123
let var = 123

3.变量需要先定义再引用,在表达式中引用未定义的变量,则表达式的结果也是未定义的。

例如:

1
2
3
4
let var1 = 1
let var2 = var1 + 1 // var1是定义的
let var3 = var4 + 1 // var4是未定义的
let var4 = 1

4.支持整数类型数据,整数数据的输入格式只需要支持十进制,支持负整数,整数取值范围 −2147483648≤≤2147483647。

例如:

1
2
let var3 = 10
let var3 = -10

5.支持整数的加 (+)、减 (-)、乘 (*)、除 (/) 四则运算,四则运算符之间没有优先级,运算数遵循左结合律,用例不考虑括号。

例如:

1
let var4 = 1 + 2 * var3

上述表达式的计算顺序是,先计算 1+2 结果为 3,再将 3 乘以 var3 得到表达式的结果。

6.支持通过 out 函数打印变量的值,函数参数只接受 1 个变量,不需要支持表达式。

例如:

1
2
let var4 = 12
out(var4)       // 将会输出12

7.表达式中如果引用了未定义的变量,则表达式的结果是未定义的。

8.如果计算结果溢出,则表达式结果是溢出。

9.变量命名符合通用语言变量规范,必须是以下划线 (_) 或者字母开头,遇到标点符号或者空格符时结束。

例如:

1
2
3
4
5
6
7
8
let _ = 1       // 变量名_是合法的
let _abc = 1    // 合法
let abc = 1     // 合法
let Abc_1 = 1   // 合法
let abc.x = 1   // 非法
let abc,x = 1   // 非法
let 12abc = 1   // 非法
let abc x = 1   // 非法

输入

  1. 每一行只有一个表达式。
  2. 最多支持 24 行输入。
  3. 每个用例输入至少有一个 out 输出表达式,可以有多个 out 输出表达式。
  4. 每个变量只会赋值 1 次。

例如:

1
2
3
4
let var1 = 1
let var2 = 3
let var3 = var1 + var2
out(var3)

输出

  1. 每遇到 1 个 out 输出表达式,则打印输出变量的值。
  2. 对于 out 行,只会输出一个 out 表达式的值。
  3. 如果 out 输出的变量未定义,则打印 <undefined>
  4. 如果表达式结果发生了整数上溢或者下溢,则对该变量的 out 输出表达式输出 <underflow> 或者 <overflow>
  5. 如果表达式非法,则打印 <syntax-error>

样例

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
输入:
let var1 = 1
out(var1)

输出:
1

输入:
out(var)

输出:
<undefined>

提示:
输出的var变量未定义。

输入:
let var1 = 1
let var2 = 3
let var3 = var1 + var2
out(var3)
out(var2)
out(var)
let var4 = -2147483649
let var5 = 2147483648
out(var4)
out(var5)
let x.y = 1

输出:
4
3
<undefined>
<underflow>
<overflow>
<syntax-error>

解答

大型模拟,定义相关函数,校验各个字符的正确性之后进行相关运算,

在计算算式的时候采用跨越一个字符的方法遍历,实现计算

代码

  1. # coding=utf-8
  2. ls = []
  3. mn = -(1<<31)
  4. mx = (1<<31) - 1
  5. inf = 10 ** 50
  6. SYNTAX_ERROR = "<syntax-error>"
  7. UNDEFINED = "<undefined>"
  8. UNDERFLOW = "<underflow>"
  9. OVERFLOW = "<overflow>"
  10. mp = {}
  11. try:
  12. while True:
  13. s = input()
  14. ls.append(s)
  15. except EOFError:
  16. pass # ctrl+d结束输入
  17. # 变量命名符合通用语言变量规范,必须是以下划线 (_) 或者字母开头,遇到标点符号或者空格符时结束。
  18. def is_variable_name(name):
  19. if len(name) == 0:
  20. return False
  21. if not (name[0].isalpha() or name[0]=='_'):
  22. return False
  23. for ch in name[1:]:
  24. if not (ch.isalpha() or ch.isdigit() or ch == "_"):
  25. return False
  26. return True
  27. # 支持整数类型数据,整数数据的输入格式只需要支持十进制,支持负整数,
  28. def is_int(s):
  29. try:
  30. int(s)
  31. return True
  32. except ValueError:
  33. return False
  34. # 将字符串转化为数字,如果他本身就是数字,返回这个数字,如果他是字母,则返回字典中他对应的数据
  35. def convert_int(s):
  36. if is_int(s):
  37. return int(s)
  38. elif s in mp.keys():
  39. return mp[s]
  40. else:
  41. return None
  42. # 处理let后面的字符串
  43. def parse_let(s):
  44. s = s.strip() #消除空白字符
  45. l,r = s.split('=')
  46. l,r = l.strip(),r.strip()
  47. if not is_variable_name(l):
  48. return SYNTAX_ERROR
  49. ls = r.split(' ')
  50. if len(ls) % 2 == 0: # 如果右侧的元素个数为偶数,则说明有问题
  51. return SYNTAX_ERROR
  52. for i in range(0,len(ls),2): #校验右侧的字符
  53. if not is_variable_name(ls[i]) and not is_int(ls[i]):
  54. return SYNTAX_ERROR
  55. for i in range(1,len(ls),2): #校验右侧的运算符
  56. if not (len(ls[i])==1 and ls[i] in "+-*/"):
  57. return SYNTAX_ERROR
  58. v = convert_int(ls[0])
  59. for i in range(1,len(ls),2): # 进行加减运算
  60. op,w = ls[i],convert_int(ls[i+1])
  61. if w is None:
  62. return
  63. if op == '+':
  64. v += w
  65. elif op == '-':
  66. v -= w
  67. elif op == '*':
  68. v *= w
  69. else:
  70. v //= w
  71. if v>mx:
  72. v = inf
  73. break
  74. elif v<mn:
  75. v = -inf
  76. break
  77. mp[l] = v
  78. # 输出字符串对应的数字
  79. def parse_out(s):
  80. s = s[1:-1] # 去除括号
  81. if s in mp.keys():
  82. x = mp[s]
  83. if x>mx:
  84. return OVERFLOW
  85. elif x<mn:
  86. return UNDEFINED
  87. return x
  88. else:
  89. return UNDEFINED
  90. for s in ls:
  91. if len(s) >= 3 and s[:3] == "let":
  92. t = parse_let(s[3:])
  93. if t is not None:
  94. print(t) #报错处理
  95. elif len(s) >= 3 and s[:3] == "out":
  96. print(parse_out(s[3:]))
  97. else:
  98. print(SYNTAX_ERROR)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/818975
推荐阅读
相关标签
  

闽ICP备14008679号