问题:
Dota2 的世界里有两个阵营:Radiant
(天辉)和 Dire
(夜魇)
Dota2 参议院由来自两派的参议员组成。现在参议院希望对一个 Dota2 游戏里的改变作出决定。他们以一个基于轮为过程的投票进行。在每一轮中,每一位参议员都可以行使两项权利中的一
项:
-
禁止一名参议员的权利
:参议员可以让另一位参议员在这一轮和随后的几轮中丧失所有的权利。
-
宣布胜利
:如果参议员发现有权利投票的参议员都是同一个阵营的,他可以宣布胜利并决定在游戏中的有关变化。
给定一个字符串代表每个参议员的阵营。字母“R”和“D”分别代表了Radiant
(天辉)和 Dire
(夜魇)。然后,如果有 n 个参议员,给定字符串的大小将是n
。
以轮为基础的过程从给定顺序的第一个参议员开始到最后一个参议员结束。这一过程将持续到投票结束。所有失去权利的参议员将在过程中被跳过。
假设每一位参议员都足够聪明,会为自己的政党做出最好的策略,你需要预测哪一方最终会宣布胜利并在 Dota2 游戏中决定改变。输出应该是 Radiant
或 Dire
。
示例 1:
输入: "RD"
输出: "Radiant"
解释: 第一个参议员来自 Radiant 阵营并且他可以使用第一项权利让第二个参议员失去权力,因此第二个参议员将被跳过因为他没有任何权利。然后在第二轮的时候,第一个参议员可以宣布胜利,因为他是唯一一个有投票权的人
示例 2:
输入: "RDD"
输出: "Dire"
解释:
第一轮中,第一个来自 Radiant 阵营的参议员可以使用第一项权利禁止第二个参议员的权利第二个来自 Dire 阵营的参议员会被跳过因为他的权利被禁止第三个来自 Dire 阵营的参议员可以使用他的第一项权利禁止第一个参议员的权利因此在第二轮只剩下第三个参议员拥有投票的权:
代码(python)
class Solution:
def predictPartyVictory(self, senate):
"""
:type senate: str
:rtype: str
"""
counts = [0, 0]
deque = collections.deque()
# 记录被枪毙的人
banned = [0, 0]
# 统计每个队伍的人数
for one in senate:
tmp = (one == 'R')
counts[tmp] += 1
deque.append(tmp)
# 只要双方都有人就继续
while all(counts):
one = deque.popleft()
if banned[one]:
# 他自己要被ban了,所以退出队列
counts[one] -= 1
banned[one] -=1
else:
# 没有被ban的,可以ban一个对方的人,然后自己下一轮继续
banned[one^1] += 1
deque.append(one)
return "Radiant" if counts[1] else "Dire"
总结
代码是copy别人的,对于这一题有思路代码却写不出来,代码能力比较差还需要继续努力,年轻人不可以熬夜但可以熬夜写代码。第一次接触到collection这个模块,这个函数还是挺方便的大家可以了解一下。我在下面提供一些该函数的一些用法:
模块collections只为我们提供了一种类型deque,这个类型的实例就是“双端队列(Double-Ended Queue)”
常用方法:
- d=deque([]) #创建一个空的双队列
- d.append(item) #在d的右边(末尾)添加项目item
- d.appendleft(item) #从d的左边(开始)添加项目item
- d.clear() #清空队列,也就是删除d中的所有项目
- d.extend(iterable) #在d的右边(末尾)添加iterable中的所有项目
- d.extendleft(item) #在d的左边(开始)添加item中的所有项目
- d.pop() #删除并返回d中的最后一个(最右边的)项目。如果d为空,则引发IndexError
- d.popleft() #删除并返回d中的第一个(最左边的)项目。如果d为空,则引发IndexError
- d.rotate(n=1) #将d向右旋转n步(如果n<0,则向左旋转)
- d.count(n) #在队列中统计元素的个数,n表示统计的元素
- d.remove(n) #从队列中删除指定的值
- d.reverse() #翻转队列