百度 秋招 2023.09.12 编程题目与题解(研发岗)

1、小红的棋子移动

小红和朋友玩游戏,棋盘为\(n\times m\)的坐标轴。有一颗棋子在坐标\((1,1)\)的位置,每次可以向上或者向右移动奇数单位,不能移动到棋盘外面,无法行动就输了,小红先手,请问小红能否必胜。 ## 输入 一行一个整数\(t\),表示有组数据。

接下来\(t\)行,每行两个整数\(n\)\(m\),表示棋盘大小。

  • \(1\le t\le 10^4\)
  • \(1 \le n,m \le 10^3\)

输出

对于每组数据,输出一行,如果小红必胜,输出Yes,否则输出No

样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
输入:
4
1 1
1 4
4 1
4 4

输出:
No
Yes
Yes
No

提示:
样例一,棋盘大小为1×1,小红无法行动,输了。
样例二,棋盘大小为1×4,小红第一次向右移动3个单位,小红获胜,朋友无法行动。
样例三,棋盘大小为4×1,小红第一次向上移动3个单位,小红获胜,朋友无法行动。

解答

由于每次移动都是移动奇数步,因此如果现在在坐标\((x,y)\),那么移动后的新坐标\((x',y')\)必定满足:\(x+y\)\(x'+y'\)的奇偶性并不同。因此,对于两个人所处的所有局面,\(x+y\)的奇偶性都是相同的

此外,当棋子不能动时,它在位置\((n,m)\)。因此,如果\(n+m\)的奇偶性和\(1+1\)相同,那么先手必败,否则先手必胜。

代码

1
2
3
4
T = int(input())
for _ in range(T):
n, m = map(int, input().split())
print("No" if (n + m) % 2 == 0 else "Yes")

2、小红的交换排列

小红有一个长度为\(n\)的排列,她可以选择两个位置,然后交换两个位置的数。

她想知道能否通过最多一次交换,使得存在一个连续子段,是长度为\(k\)的排列。

排列是指一个长度为\(len\)的整数数组,数组中包含\(1\)\(len\)的每个数目每个数只出现一次。 ## 输入 一行两个整数\(n,k\),表示排列长度和连续子段长度。

一行\(n\)个整数\(a_1,a_2,\dots,a_n\),表示排列。

  • \(1\le k\le n\le 10^5\)

输出

如果能够通过最多一次交换,存在一个连续子段是排列,输出YES,并输出交换的位置:先输出一个整数\(x(0\le x\le 1)\),然后输出\(x\),每行两个整数\(u,v\),表示交换位置\(u,v\)

否则输出NO

样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
输入:
5 3
1 2 3 4 5

输出:
YES
0

提示:
子段[1,2,3]是长度为3的排列。

输入:
5 4
1 5 3 4 2

输出:
YES
1
2 5

提示:
交换a2, a5后,[1,2,3,4,5]

解答

由于它这里只需要产生一个长度为\(k\)的排列即可,因此我们可以将这个问题简化一下:将\(a_i\le k\)的所有数对应位置看成是一个比特\(1\),其余的所有位置看成是比特\(0\)。由此我们得到了一个长度为\(n\)的比特串\(s\),其中包含了\(k\)\(1\),问题是是否可以通过一次交换两个位置中的比特,从而使其中所有比特\(1\)都相邻?

可以发现,无非只有\(4\)种情况满足题目答案,分别如下:

1
2
3
4
......000000011111111100000......
......010000011111111100000......
......000000011111111100010......
......000000011111011110000......

其中,第\(1\)种情况是已经符合答案的,不需要进行任何操作;第\(2\)种和第\(3\)种情况是对称的,有\(1\)\(1\)比特游离在外,剩下的\(k-1\)个比特相邻,这种方法是选择这\(k-1\)个比特中,将左侧的\(0\)或者是右侧的\(0\)和游离在外的\(1\)比特交换即可;第\(4\)种情况则是\(k\)\(1\)比特中间夹杂了\(1\)\(0\)比特,只需要选择将它和最左侧或者是最右侧的\(1\)比特交换即可。

因此我们只需要分类讨论即可得出答案。

代码

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
def solve():
n, k = map(int, input().split())
a = list(map(int, input().split()))
b = [i for i, x in enumerate(a) if x <= k]
l, r = b[0], b[-1]
if r - l == k - 1:
return 1, []
elif r - l == k:
loss = list(set(range(l, r + 1)) - set(b))[0]
other = b[0]
return 1, [(loss, other)]
else:
if b[-2] - b[0] == k - 2:
l, r, x = b[0], b[-2], b[-1]
elif b[-1] - b[1] == k - 2:
l, r, x = b[1], b[-1], b[0]
else:
return 0, []
if l == 0:
return 1, [(r + 1, x)]
else:
return 1, [(l - 1, x)]


flag, sol = solve()
print("YES" if flag else "NO")
if flag:
print(len(sol))
for x, y in sol:
print(x + 1, y + 1)

3、小红的方法重载

请你编写一个系统用来管理方法的重载和调用。

共有以下2种操作:

  1. 创建一个方法: 输入的格式为:Type name(var1 a1, var2 a2......)",大括号和方法里内容 被省略。

  2. 调用一个方法: 输入的格式为:"name(var1, var2......)"

以上变量,vari代表变量类型,ai代表变量名,name代表方法名Type代表返回类型,均为由小写字母组成的字符串。

请你在每次操作后给出系统反馈。

  1. 创建方法时,若创建成功,则输出一个字符串"ok."。否则输出一个字符串"method xxx is already defined."

  2. 调用方法时,若调用成功,则输出一个字符串"ok."。若方法名不存在,则输出"cannot find symbol xxx."。若方法名存在但方法内部的变量类型错误,则输出"method xxx cannot be applied to given types."

输入

第一行输入一个正整数\(q\),代表操作次数。

接下来的\(2\times q\)行,每\(2\)行代表一次操作。

第一行为一个正整数\(op\),代表操作类型。

第二行为一个字符串,代表一次操作。

  • \(1\le q\le 100\)
  • \(1\le op\le 2\)

操作的字符串长度不超过\(100\),且格式保证合法。

输出

输出\(q\)行字符串,代表每次操作系统的反馈。

样例

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
输入:
7
1
int f(int x)
1
int g(int x,String s)
2
f()
1
void f(double x,double y)
2
f(double,double)
2
solve(int,String)
1
void f(int y)

输出:
ok.
ok.
method f cannot be applied to given types.
ok.
ok.
cannot find symbol solve.
method f is already defined.

提示:
第一次操作,创建方法成功。
第二次操作,创建方法成功。
第三次操作,调用无参方法f(),虽然已经有了以名为的方法,但参
数类型不对,所以调用失败。
第四次操作,创建方法成功(本次重载了f方法)
第五次操作,调用方法f(double,double)成功。
第六次操作,调用方法solve(int,String),显然不存在该方法。
第七次操作,创建方法void f(int y),由于已经存在一个单int型参数的f方法,因此创建失败。

解答

可以直接按照题意进行模拟。将每一次定义方法和调用方法都解析成一个二元组:(方法名,参数类型列表),并且使用一个字典来存放对应方法名的参数列表。接下来就是直接模拟整个过程即可。

代码

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
mp = {}


def parse_define(s):
s = s[s.find(' ') + 1:]
method_name = s[:s.find('(')]
t = s[s.find('(') + 1:s.find(')')].split(',')
params_list = tuple(s[:s.find(' ')] for s in t)
return method_name, params_list


def parse_invoke(s):
method_name = s[:s.find('(')]
params_list = tuple(s[s.find('(') + 1:s.find(')')].split(','))
return method_name, params_list


def solve_define(s):
method_name, params_list = parse_define(s)
if method_name not in mp.keys():
mp[method_name] = set()
if params_list in mp[method_name]:
return "method {} is already defined.".format(method_name)
else:
mp[method_name].add(params_list)
return "ok."


def solve_invoke(s):
method_name, params_list = parse_invoke(s)
if method_name not in mp.keys():
return "cannot find symbol solve."
elif params_list not in mp[method_name]:
return "method {} cannot be applied to given types.".format(method_name)
else:
return "ok."


T = int(input())
for _ in range(T):
op, s = input(), input()
print(solve_define(s) if op == '1' else solve_invoke(s))

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
Ujimatsu Chiya 微信 微信
Ujimatsu Chiya 支付宝 支付宝