Java 区间猜数游戏
我刚刚开始了在CodeChef上成为一名更好的编码员的漫长道路。人们从标有“容易”的问题开始,我也这样做了 问题陈述定义了以下内容-:Java 区间猜数游戏,java,algorithm,range,Java,Algorithm,Range,我刚刚开始了在CodeChef上成为一名更好的编码员的漫长道路。人们从标有“容易”的问题开始,我也这样做了 问题陈述定义了以下内容-: n,其中1考虑以下更容易理解的方法。画出整数的1d轴,并在其上放置k提示。每个提示都可以被视为“(”或“)”或“=”(分别大于、小于或等于) 例如: -----(---)-------(--=-----)-----------) 现在,真值在这个轴的40个值中的某个位置,但实际上只有8个段值得检查,因为在一个段内的任何地方,真/假提示的数量保持不变。 这意味
n
,其中1考虑以下更容易理解的方法。画出整数的1d轴,并在其上放置k提示。每个提示都可以被视为“(”或“)”或“=”(分别大于、小于或等于)
例如:
-----(---)-------(--=-----)-----------)
现在,真值在这个轴的40个值中的某个位置,但实际上只有8个段值得检查,因为在一个段内的任何地方,真/假提示的数量保持不变。
这意味着您可以根据提示在轴上的顺序扫描它们,并在该点上维护一个真正提示的计数器
在上面的例子中,它是这样的:
segment counter
-----------------------
-----( 3
--- 4
)-------( 3
-- 4
= 5 <---maximum
----- 4
)----------- 3
) 2
段计数器
-----------------------
-----( 3
--- 4
)-------( 3
-- 4
=5如果目标数=1,则计算谎言数(将其存储在变量lies
)
让目标=1
按语句各自的值对语句进行排序和分组
遍历语句
- 将
target
更新为当前语句组的值。根据这些语句中有多少将变为true或false来更新lies
< > > > P> >将代码< >目标< /代码>更新为该值+ 1(为什么这样做?考虑当您有<代码> 5 < /COD>和<代码> < 7 < /代码> ->代码> 6 /代码>可能是最佳值),并适当地更新<代码>谎言>代码>(如果下一个语句组的值为此值,则跳过此步骤)。
谎言的最小值
运行时间:
O(k)
用于初始计算
O(k log k)
用于排序
O(k)
用于迭代
O(k log k)
total.我对这个问题的看法与Eyal Schneider的看法相似。从这一点开始,将'>'表示为更大,''和'='(在一个名为int[]greaterAndEqual
的数组中)。我们可以很容易地看到,在特定点i
中的谎言数等于
lessAndEqual[i] + greaterAndEqual[i + 1]
通过在O(n)中进行两次扫描,我们可以轻松地填充lessAndEqual
和greaterAndEqual
数组,并在O(nlogn)中对所有提示进行排序,结果时间复杂度为O(nlogn)
注意:当提示中的
num
等于时,应特别处理。还要注意num的范围是10^9,这要求我们有一些形式的点压缩,以将数组放入内存中为什么不尝试学习段树?如果不理解基本概念,就很难再进一步了ke段树,二元索引树…对于轴上的一个点,谎言的数量等于'('和'='在这一点之后和''和'='在这一点之前,我对吗?这个计数方案应该进行两次扫描:)@Phamtrong:是的,你需要一次扫描来确定计数器的初始值,然后进行第二次扫描,以便在分段之间跳转时跟踪计数器的值。扫描是线性的,用k表示。非常好,我认为这比我想象的要好,当你只需要跟踪一个数字:)
lessAndEqual[i] + greaterAndEqual[i + 1]