生活大爆炸版石头剪刀布

前几日偶然间发现,14年母校的信息学成绩十分了得,在 NOI 2014 中获得了一枚铜牌在 NOIP 2014 中获得了五个一等、两个二等,真是后生可畏,一代更比一代强啊。

好久好久没有做过算法题了。从 NOIP 2003 到 NOIP 2008,从没进复赛,到以总分第二获得一等奖,再到后面几年不堪的表现,NOIP 陪伴了我的整个中学。今天找来 NOIP 2014 的复赛题看了看,发现第一题挺水的,于是做了做。可惜的是 free pascal 在 Yosemite 上竟无法安装,所以决定用 python 来写,顺便再熟悉一下 python。

题目可在这儿查看或自行查找,是 NOIP 2014 提高组复赛 Day1 的第一题:生活大爆炸版石头剪刀布。

题目不难,数据规模也不大,把整个过程模拟一下就好了。唯一值得说的是,将题目中的胜负关系表格补全后形成一个二维数组,就能很方便地在这个数组中查询到每一轮出拳的结果。

rps.py
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
filein = open("rps.in","r")
arrInput = filein.readline().split()
n = int(arrInput[0])
na = int(arrInput[1])
nb = int(arrInput[2])
arrInput = filein.readline().split()
arrA = [int(x) for x in arrInput]
arrInput = filein.readline().split()
arrB = [int(x) for x in arrInput]
filein.close()
resultTable = [[0,0,1,1,0],[1,0,0,1,0],[0,1,0,0,1],[0,0,1,0,1],[1,1,0,0,0]]
scoreA = 0
scoreB = 0
for i in range(0,n):
solutionA = arrA[i % na]
solutionB = arrB[i % nb]
scoreA += resultTable[solutionA][solutionB]
scoreB += resultTable[solutionB][solutionA]
fileout = open("rps.out","w")
strScore = str(scoreA) + ' ' + str(scoreB) + '\n'
fileout.write(strScore)
fileout.close()

程序很简单。刚开始是读取数据:nnanb 的含义如题,arrAarrB 保存 A 和 B 的策略。resultTable 是前面说过的胜负关系数组,resultTable[甲,乙] 表示甲对乙的得分。for 循环中是对 n 轮出拳进行模拟:用当前的轮数与 A 或 B 的循环节长度取模,就能得到本轮 A 和 B 的策略,用这两个策略去 resultTable 中查询,就能得到 A 和 B 本轮的得分,保存于 scoreAscoreB。最后输出结果。

对 python 了解不多,如果有写的不妥之处,欢迎拍砖。