[R26C]石头剪刀布
- 难度 提高
- 时限 1s
- 空限 512m
- 模拟
数据规模:,,所有手势均为
0、1、2之一。
思路
apiadu 必须从 位对手中选一位,与他在 轮中逐一过招。每位对手的得分是独立的,因此只需对每位对手算出 轮的总得分,再取所有对手的最大值即为答案。
胜负判定可以统一成一个式子。设 apiadu 出 ,对手出 ,记 :
- :
apiadu赢,得 分; - :
apiadu输,失 分; - :平局,分数不变。
简单验证:石头(0)胜剪刀(1)对应 , ✓;布(2)胜石头(0)对应 , ✓;其余同理。
最大可能的总得分绝对值不超过 ,用 Int64 即可。
复杂度
时间 ,最多约 次比较;空间 ,只需保存 apiadu 的手势序列。
仓颉实现
import std.env.*
import std.convert.*
main(): Int64 {
let reader = getStdIn()
let head = reader.readln().getOrThrow().split(" ", removeEmpty: true).map({ p: String => Int64.parse(p) })
let n = head[0]
let m = head[1]
let y = head[2]
let z = head[3]
let apiadu = reader.readln().getOrThrow().split(" ", removeEmpty: true).map({ p: String => Int64.parse(p) })
var best = Int64.Min
var i = 0
while (i < n) {
let opp = reader.readln().getOrThrow().split(" ", removeEmpty: true).map({ p: String => Int64.parse(p) })
var score = 0
var j = 0
while (j < m) {
let a = apiadu[j]
let b = opp[j]
let diff = (b - a + 3) % 3
if (diff == 1) {
score += y
} else if (diff == 2) {
score -= z
}
j++
}
if (score > best) {
best = score
}
i++
}
println(best)
return 0
}