题目大意
有一个魔术盒子,按照给定的顺序向里面放置3种不同颜色的球。当3种颜色的球数量之差满足 x, y, z时,盒子中的球全部都会消失。询问对于给定的放置顺序,盒子中最多同时存在过多少个球。
解题思路
本题作为该场笔试的第一题,难度并不高,是一个比较基础的模拟题目。我们记录盒中三种颜色的球的数量。每当放置一个新的球时,更新球的数量,并且判断球数量的差值是否满足了 x, y, z的关系。若满足了消失的条件,则更新我们的最大球数量,并且将计数器清0。
其伪代码写为:
color = []
// 放置序列,我们用0,1,2分别表示3种颜色的球
count = [0,0,0]
// 初始化计数器
max = 0
// 初始化最大值
For i = 1..n // 枚举放置的顺序
count[ color[i] ] = count[ color[i] ] + 1 // 对应颜色加1
If (count满足消除条件) Then
total = sigma(count) // 统计当前有多少球
If max < total Then // 更新最大值
max = total
End If
count = [0, 0, 0] // 重置计数器
End If
End For
接下来要处理的是如何判定当前球的数量是否满足消失条件:
根据球的数量计算出3个差值,不妨记为 a, b, c。这3个差值和x, y, z的对应关系可能出现6种情况,所以一个简单的写法就是暴力枚举这六种对应情况:
Check(count):
a = abs(count[0] - count[1])
b = abs(count[1] - count[2])
c = abs(count[2] - count[0])
if ((a == x and b == y and c == z) or (a == x and c == y and b == z)
or (b == x and a == y and c == z) or (b == x and c == y and a == z)
or (c == x and a == y and b == z) or (c == x and b == y and a == z))
Return True;
Return False;
或者我们可以对这三个值进行排序,按从大到小的顺序进行比较:
condition = [x, y, z];
sort(condition);
Check(count):
delta = [abs(count[0] - count[1]), abs(count[1] - count[2]), abs(count[2] - count[0])];
sort(delta); // 排序
if (delta[0] == condition[0] and delta[1] == condition[1] and delta[2] == condition[2])
Return True;
Return False;
选择哪一种方法,其时间复杂度只有常数上的区别,第二种相对于第一种来说扩展性更好一点。
放第三个时,盒子中是RBY,满足消失条件,就直接消失了。