我无法弄清楚这个问题:想象我们有M灯。起初他们都是关闭的。一个人做N动作。移动是当人将所有灯从a切换到b(包括)时。问题是:在这些动作之后将会有多少个灯泡亮起。限制是:
以下是输入示例:
12 3
2 6
2 6
1 3
这意味着有12个灯泡,这个人做了3次动作。在他的第一步中他切换了2到6号灯(现在我们有2,3,4,5和6)。在他的第二步中,他再次拨打了2到6的灯(所以现在所有的灯再次关闭)。在他的最后一步,他切换了1到3的光线(灯1,2和3打开)。所以答案是3,因为在这一系列动作之后只有3个韧带开启。
我需要一些帮助来解决我应该如何解决这个问题。简单地创建一个布尔数组并切换它是行不通的,因为数字可以达到多大。
答案 0 :(得分:3)
假设您不需要动态数据结构(您有连续的更新/查询),我会使用扫描技术来解决这个问题,使用一个简单的逻辑:
1)对所有段末尾进行排序(在您的示例中,它将导致[1,2,2,3,6,6])
2)扫描列表,保持“奇偶校验”变量。每当遇到新的结束时,切换奇偶校验。扫描仅访问两端,因此扫描的任何步骤都“看到”具有相同状态的灯泡的段(打开或关闭,具体取决于奇偶校验变量)。
伪代码:
countTurnedOn(L : Array of Segment objects) {
E = create empty list
for (all s in L) {
E.add(s.begin)
E.add(s.end+1)
}
sort(E)
count = 0
parity = 0
pos = 0
for (i in 0 .. E.length-1) {
newpos = E[i]
count = count + (newpos - pos) * parity
parity = (parity + 1) % 2
pos = newpos
}
return count
}
答案 1 :(得分:1)
问题是您希望压缩有关灯泡打开或关闭的信息。 - 没有专门用于单个灯泡的阵列中的元素(甚至是单个位),您必须专注于打开或关闭灯串。
LightString
将包含以下信息:
length
(灯泡数量为长整数)state
( on 或 off 由1/0或布尔值表示)你可以在动态容器中保存一系列字符串,我推荐一棵树,因为你会做很多插入(可能还有一些删除)。您从一个字符串{length:M, state:false}
开始。
当您处理移动时,您有两个相同的步骤。对于第一个数字(a
):
a
对于b
,您也可以这样做。
你的例子(第一步):
[{length:12, state:false}]
[{length:1, state:false},{length:11, state:false}]
[{length:1, state:false},{length:11, state:true}]
[{length:1, state:false},{length:5, state:true},{length:6, state:true}]
[{length:1, state:false},{length:5, state:true},{length:6, state:false}]
执行某个步骤后,您可能需要进行一些清理,以保持较低的内存使用率和访问时间:合并具有相同状态的连续字符串。删除零长度字符串。