7-1 小偷踩点 (分数 20)
俗话说不怕贼偷,就怕贼惦记。
小偷在作案前有时会在居民家的门、墙上做一些标记,每一种记号代表一个含义,一般人看不懂,但同行一看便知道这个家庭的情况。不过派出所干警也不是吃素的,很快破译了这些记号的含义(如上图),并且在辖区内广为张贴,告知居民。
随后小偷们又改变了方法,将这些记号从 1 到 N 编号,然后将这些编号按照某种规则重新打乱再做标记,标记变成了一串数字。不过这种新的编号方法又被破译了!干警们发现这些数字的规律可以用一个二维矩阵来表示:矩阵有 10 列,顺序对应数字 0 到 9;矩阵一般不超过 10 行,每行对应一个 0 到 9 之间的数字,这些数字保证不重复。小偷的新标记由若干个两位数组成,每个数字的十位对应行、个位对应列,而对应位置上的数字就是原始标记的编号。
如上图 40 种标记从上到下、从左到右顺序编号后,按下图所示的规律打乱,则如果我们看到标记“71”,就是行标记为 7,列标记为 1 的单元格对应的数字 11,对应原始标记中第 11 个,即“很有钱”。那么标记“71 78 57”就表示原始标记的第 11、8、7 号,意思是“很有钱”、“没有防范”、“计划行动”。
本题就请你编写程序,自动破译小偷的新标记。
输入第一行给出 2 个正整数:N(≤100)为小偷的原始标记个数,M(≤10)为新标记对照矩阵的行数。
随后 N 行,第 i 行给出第 i 个标记的解释,由不超过 100 个英文字母和空格组成。
接下来一行给出 M 个数字,为 0 到 9 之间的数字,保证不重复,其中第 i 个数对应矩阵第 i 行。
接下来 M 行,每行给出 10 个数字,或者是 1 到 N 之间的一个编号,或者是 −1 表示没有对应的编号。
最后一行给出小偷留在墙上的数字标记,格式为:
k t[1] ... t[k]
其中 k
是数字个数(不超过 N),后面跟着 k
个数字。
对小偷留下的每个数字,在一行中输出其对应的意义,顺序与输入顺序相同。如果没有对应的意义,则在对应行中输出 ?
。
10 2
jia li you ren
kong fang zi
jia you e gou
dan shen
hen you qian
xiao xin lin ju
you bao jing qi
jin kuai dong shou
xia ci zai lai
bu bi jin ru
6 2
-1 6 5 1 -1 10 3 4 -1 9
2 4 7 -1 3 -1 5 -1 8 2
5 20 64 61 22 13
kong fang zi
?
xiao xin lin ju
you bao jing qi
?
提交结果:
代码(Python3):
n, m = list(map(int, input().split()))
a = {}
b = {}
for i in range(n):
data = input()
a[i + 1] = data
num = list(map(int, input().split()))
for i in range(m):
data1 = list(map(int, input().split()))
b[num[i]] = data1
data2 = list(map(int, input().split()))
for i in data2[1:]:
if i // 10 not in b.keys():
print("?")
continue
else:
index = b[i // 10][int(i % 10)]
if index == -1:
print("?")
else:
print(a[index])
7-2 盲盒包装流水线 (分数 25)
众所周知,PAT 有 9 枚徽章,分别对应青铜、白银、黄金、白金、钻石、大师、王者、大圣、天神这 9 个段位,只有成绩非常优秀的考生才有资格获得刻有自己名字的徽章。现在,PAT 制作了徽章的小型纪念版,要制成盲盒给大家玩了!
下图是一条盲盒包装流水线的示意图。首先徽章通过进货口被压入货栈里,空盒在履带上从左向右传送。每次从货栈里弹出一枚徽章,进入打包机,装入一只空盒,打包后继续向右边传送。当货栈为空时,打包机会暂停,等待下一批徽章压入货栈。
每只盒子都有一个编号,小拼姐姐手里有进入流水线的空盒编号顺序表,也有每一批送往货栈的徽章顺序表,这样她其实可以知道每只盒子里装了哪种徽章。有些小朋友收到了盲盒,就想在拆封前问无所不知的小拼姐姐,盒子里的徽章是哪一种。但是因为盲盒总量有 105 这么多,小拼姐姐可记不住每只盒子里装的是什么,于是你就被请来写个程序帮小拼姐姐回复这种信息。
输入第一行给出 2 个正整数,分别为盲盒总量 N(≤105)和货栈容量 S(≤100)。接下来一行给出 N 只盒子的编号,编号由 5 位数字组成,给出的顺序是空盒进入传送带的顺序。随后 N/S(保证是整数)行,每行给出一批 S 枚徽章的类型,为 1-9 的数字,给出的顺序是从进货口入栈的顺序。
再下面给出一个正整数 K(≤104),为查询次数。随后 K 行,每行给出一个 5 位编号。
对每个查询编号,在一行中输出该盒子中装的徽章类型。如果编号是错误的,则在一行中输出 Wrong Number
。
10 5
00132 10093 92001 23333 66666 88888 09009 34658 82750 69251
1 2 3 4 5
9 8 7 6 1
5
66666
88888
69251
55555
10093
1
1
9
Wrong Number
4
提交结果:
代码(Python3):
n, m = list(map(int, input().split()))
a = {}
b = []
name = input().split()
for i in range(n // m):
data = list(map(int, input().split()))
for j in data[::-1]:
b.append(j)
for i in range(n):
a[name[i]] = b[i]
num = int(input())
for i in range(num):
data1 = input()
if data1 not in a.keys():
print("Wrong Number")
else:
print(a[data1])
7-3 到底爱不爱我(分数 25)
古代少女有了心上人时,会悄悄折一条树枝,揪那枝上的叶子,揪一片叶子念一句“爱我”,再揪一片念一句“不爱我”…… 这样揪落最后一片叶子的时候,看看是停在“爱”还是“不爱”。
但聪明的慧娘一眼洞穿,只要数一下叶子有多少片,根据这个数字的奇偶性判断是以“爱”开始还是以“不爱”开始,就总是可以最后落在“爱”上。这个游戏顿时就变得无趣了 —— 真的是文科生制造浪漫,理科生杀死浪漫。
于是有着工科生大脑的慧娘打算另外制作一个更有趣的浪漫游戏。她用不同植物的枝条做成了三种“情枝”:
慧娘将这些树枝摆放在院子里,布了一个“情阵”,先选一根特殊的枝条作为初试一枝,从这枝条的根部开始,扩散开去,令它们根枝相连。然后她在末梢的枝杈旁随意写下“爱”或“不爱”。现在请你写个程序帮她算出来,在初始一枝的根部,她能得到“爱”还是“不爱”?
输入在第一行中给出正整数 N(≤30),是慧娘制作的情枝数量。这里假设她将所有的情枝从 1 到 N 做好了编号。随后 N 行,第 i 行给出第 i 枝的描述,格式为
类型 左分枝连接的编号 右分枝连接的编号
其中 类型
为 1 代表专情、2 代表博爱、3 代表情变。当然如果是情变枝,则后面跟的是其唯一末端连接的情枝编号,并没有两个分枝的信息。如果一个分枝是末梢,并没有连接其它枝条,则对应编号为 0。
接下来一行中给出正整数 K(≤30),是慧娘询问的次数。以下 K 行,每行给出一个由 0
和 1
组成的字符串,其中 0
表示“不爱”,1
表示“爱”—— 这是慧娘从左到右在每个枝杈末梢处写下的。(注意:“从左到右”的意思是,我们从初试一枝出发去遍历所有枝条的末梢时,总是遵循先遍历左边情阵、再遍历右边情阵的顺序)
对慧娘的每个询问,如果她在初始一枝的根部能得到“爱”,就输出 Ai
;否则输出 BuAi
。
6
2 6 4
1 0 0
3 1
2 0 0
3 0
1 5 2
5
11111
00000
11100
10011
01100
BuAi
Ai
Ai
BuAi
BuAi
样例对应的情阵以及慧娘第 3 问的情势如图所示,其中完整的心对应 1
,裂开的心对应 0
。
提交结果:
代码(Python3):
def add(a, b):
global idx
e[idx] = b
ne[idx] = h[a]
pa[b] = a
h[a] = idx
idx += 1
def reform(str1):
for i in str1:
q.append(int(i))
def dfs(node):
if h[node] == -1:
ans = 0
if classer[node] == 1:
left = q[0]
q.pop(0)
right = q[0]
q.pop(0)
ans = left & right
elif classer[node] == 2:
left = q[0]
q.pop(0)
right = q[0]
q.pop(0)
ans = left | right
elif classer[node] == 3:
left = q[0]
q.pop(0)
ans = not left
return ans
son_node = [0, 0]
sub = 0
ans = 0
i = h[node]
while i != -1:
son_node[sub] = e[i]
sub += 1
i = ne[i]
if classer[node] == 1:
if son_node[0] != 0:
num1 = dfs(son_node[0])
else:
num1 = q[0]
q.pop(0)
if son_node[1] != 0:
num2 = dfs(son_node[1])
else:
num2 = q[0]
q.pop(0)
ans = num1 & num2
elif classer[node] == 2:
if son_node[0] != 0:
num1 = dfs(son_node[0])
else:
num1 = q[0]
q.pop(0)
if son_node[1] != 0:
num2 = dfs(son_node[1])
else:
num2 = q[0]
q.pop(0)
ans = num1 | num2
elif classer[node] == 3:
ans = not dfs(son_node[0])
return ans
idx = 0
h = [-1 for _ in range(100)]
pa = [-1 for _ in range(100)]
e = [0 for _ in range(100)]
ne = [0 for _ in range(100)]
q = []
classer = [0 for i in range(100)]
n = int(input())
for i in range(1, n + 1):
data = list(map(int, input().split()))
classer[i] = data[0]
if classer[i] == 1 or classer[i] == 2:
left = data[1]
right = data[2]
if left != 0 or right != 0:
add(i, right)
add(i, left)
elif classer[i] == 3:
left = data[1]
if left != 0:
add(i, left)
root = 0
for i in range(1, n + 1):
if pa[i] == -1:
root = i
break
k = int(input())
for i in range(k):
str1 = input()
reform(str1)
ans1 = dfs(root)
if ans1:
print("Ai")
else:
print("BuAi")
7-4 皆大欢喜(分数 30)
喵星人素以有个性著称,铲屎官很难用一种玩具让家里所有的喵主子都高兴起来。于是铲屎官调研了一下各种玩具,记录下每种玩具能让哪些喵高兴、同时让哪些喵生气、另外还有哪些喵无感。现在铲屎官来向你求助,请你告诉他如何用最少的玩具,让所有的喵都高兴起来。
注意:如果一只喵处于高兴的状态,那么它会一直高兴着,直到见到让它生气的玩具;同样地,如果喵不高兴,它会一直不高兴,直到见到让它高兴的玩具。如果一样玩具令喵无感,则不会改变它原来的状态。
输入第一行给出两个正整数,分别是 N (≤10),为喵的个数;以及 M(≤10),为玩具的个数(假设玩具从 1 到 M 编号)。随后 M 行,每行对应一种玩具,顺序给出 N 只喵的状态:1 表示高兴,-1 表示生气,0 表示无感。
假设初始状态下没有玩具,所有喵都不高兴。在一行中给出逗喵玩具的编号顺序,使得按这个顺序把玩具给喵,能令所有的喵都高兴起来。要求输出最少玩具的解。当这种解不唯一时,输出最小编号序列。题目保证存在解。一行中的数字以 1 个空格分隔,行首尾不得有多余空格。
序列 { a1,a2,...,an } 小于序列 { b1,b2,...,bn } 的定义是:存在 1≤k 提交结果: 代码(Python3):输入样例:
3 4
-1 1 0
1 1 -1
0 -1 1
1 0 0
输出样例:
3 1 4
import copy
import sys
def check():
for i in range(n):
if state[i] != 1:
return False
return True
def set1(u):
for i in range(n):
if a[u][i] == 1:
state[i] = 1
elif a[u][i] == -1:
state[i] = -1
def dfs(u):
global num
global cnt
global state
global ans
backup = copy.deepcopy(state)
set1(u)
st[u] = 1
res[cnt] = u
cnt += 1
if check():
if cnt < num:
num = cnt
ans = copy.deepcopy(res)
for i in range(m):
if not st[i]:
st[i] = 1
if dfs(i):
return True
st[i] = 0
st[u] = 0
state = copy.deepcopy(backup)
cnt -= 1
return False
state = [-1 for _ in range(11)]
a = [[0 for _ in range(11)] for _ in range(11)]
ans = [0 for _ in range(11)]
res = [0 for _ in range(11)]
st = [0 for _ in range(11)]
num = 100
cnt = 0
n, m = list(map(int, sys.stdin.readline().split()))
for i in range(m):
data = list(map(int, sys.stdin.readline().split()))
for j in range(n):
a[i][j] = data[j]
for i in range(m):
dfs(i)
for i in range(num):
print(ans[i] + 1, end="")
if i != num - 1:
print(end=" ")