1
18
我认为一个关键是首先了解K值的模式及其增长的速度。基本上,你有:
找到给定K的最小X值
编辑 好的,我们正在寻找一种算法,在值LO..HI的范围内计算K=2,3,4的值的数量,而不迭代整个范围。因此,第一步是找到i=1..59时位计(x)==i范围内的值的个数(因为我们只关心10^18和10^18<2^60)。因此,将范围lo..hi分解成2次方的子范围,它们只在较低的n位上不同——x*(2^n)…(x+1)*(2^n)-1形式的范围。我们可以很容易地把任意的lo..hi区间分解成这样的子区间。对于每个这样的子范围,将有具有i+位计数(x)设置位的选择(n,i)值。 所以我们把所有的子范围加在一起,得到一个1..59的计数向量,然后迭代,把那些K值相同的元素加在一起,得到我们的答案。 编辑 这里有一个C程序来完成我之前描述的:
对于高达2^63-1(LONGLONG_MAX)的值,它运行良好。
编辑
输出
|
2
6
这个答案背后的想法可以帮助您快速开发解决方案。具有范围0…2 ^ n的潜在算法的复杂性将是O(n)在最坏的情况下(假设长算术的复杂性是O(1))如果编程正确,它应该毫不费力地处理n=1000000毫秒。 假设我们有以下值:
范围LO..HI中的最低可能N1为0 因此,N2..NN部分的计算只针对32个值中的一个(即0..31)。 即使没有电脑,也可以简单地完成。 当X=0时,我们有count(N1=X)=1,这是以下值:
当X=1时,我们有count(N1=X)=31,这些值如下:
当X=2时,我们有以下模式:
29-“0”和2-“1”可以形成多少个唯一字符串? 假设最右边的“1”(#1)从左向右循环,我们得到以下图片:
现在我们有30个唯一的字符串,同时将“1”(#1)从左向右移动,现在不可能 通过向任何方向移动“1”(#1),创建唯一字符串。这意味着我们应该向右移动1(#2),
现在我们再做一次“1”(#1)的循环
现在我们有29个唯一的字符串,继续这个操作28次,我们得到以下表达式
当X=3时,图片保持相似,但我们正在移动“1”(1)、“1”(2)、“1”(3) 移动“1”(#1)将创建29个唯一字符串,当我们开始移动“1”(#2)时 29+28+。。。+1=435个唯一字符串,之后我们将处理“1”(#3),因此
让我们试着解决一般情况,即当我们有N个零和M个一时。 长度为(N+M)的字符串的置换总数等于(N+M)! 此字符串中“0”个重复项的数量等于N! 此字符串中“1”个重复项的数量等于M!
编辑:
现在让我们考虑一个真实的例子:
那么我们如何将我们唯一的置换公式应用到这个例子中呢?因为我们不知道 许多“1”位于LO下方,有多少“1”位于HI上方。 所以让我们数一数这些在LO之下和HI之上的排列。 让我们记住我们是如何循环“1”(1)、“1”(2)、。。。
正如您所看到的,这个循环过程平稳地减少了十进制值。所以我们需要计算 最坏的情况可以产生多达32!/(16岁!*16!)=601080390个循环,我们将循环很长时间:) 在我们的例子中,我们希望计算转换的周期数
那么有多少个循环导致了这种转变
?
等于以下循环:
执行我们需要的以下动作:
因此收到28+27+。。。+1+1=406+1 但我们以前见过这个值,它是唯一置换量的结果,它是 为2“1”和27“0”计算。这意味着移动时的循环次数
等于移动
所以这意味着如果我们有M个零和N个一,想要把U'1的块移到右边,我们需要 执行以下循环量:
编辑:
现在让我们回到现实生活中的例子:
变换(假设N1=6)
这等于:
关于LO,实际上我们骑车的方向没有区别 因此,对于计算LO,我们可以进行反向循环:
我不会提供解决方案的剩余部分。抓住剩下的部分并不难。祝你好运! |
3
2
我认为这是离散数学中的一个问题,
|
4
1
佐布吉布, 这个问题的关键不是要理解K的增长有多快,而是它本身是如何增长的。第一步是理解二进制数是如何计算的(正如你的教练所说),因为这决定了关于K是如何确定的。二进制数遵循一种模式,这种模式在计算正数位数时是不同的。这是一个单一的渐进重复模式。我要用一种不同寻常的方式来证明。。。 Assume i is an integer value. Assume b is the number of positive bits in i i = 1; b = 1; i = 2; 3; b = 1; 2; i = 4; 5; 6; 7; b = 1; 2; 2; 3; i = 8; 9; 10; 11; 12; 13; 14; 15; b = 1; 2; 2; 3; 2; 3; 3; 4; i = 16; 17; 18; 19; 20; 21; 22; 23; 24; 25; 26; 27; 28; 29; 30; 31; b = 1; 2; 2; 3; 2; 3; 3; 4; 2; 3; 3; 4; 3; 4; 4; 5; I assure you, this pattern holds to infinity, but if needed you should be able to find or construct a proof easily. 如果您查看上面的数据,您会注意到一个与2^n相关的不同模式。每次整数指数为2时,该模式将通过包含前一个模式的每个项而重置,然后前一个模式的每个项递增1。因此,要得到K,只需将新数字应用于上面的模式。关键是找到一个单一的表达式(这是有效的)来接收你的位数。 为了演示,再一次地,你可以从中进一步推断出一个新的模式,因为它是静态的,并且遵循相同的过程。下面是用K值修改的原始数据(基于递归)。 Assume i is an integer value. Assume b is the number of positive bits in i i = 1; b = 1; K = 1; i = 2; 3; b = 1; 2; K = 1; 2; i = 4; 5; 6; 7; b = 1; 2; 2; 3; K = 1; 2; 2; 3; i = 8; 9; 10; 11; 12; 13; 14; 15; b = 1; 2; 2; 3; 2; 3; 3; 4; K = 1; 2; 2; 3; 2; 3; 3; 2; i = 16; 17; 18; 19; 20; 21; 22; 23; 24; 25; 26; 27; 28; 29; 30; 31; b = 1; 2; 2; 3; 2; 3; 3; 4; 2; 3; 3; 4; 3; 4; 4; 5; K = 1; 2; 2; 3; 2; 3; 3; 2; 2; 3; 3; 2; 3; 2; 2; 3;
如果你注意到,K遵循类似的模式,有一个特殊的条件。。。每次b是2的幂,它实际上会将K值降低2。所以,如果你遵循二元级数,你应该能够很容易地映射你的K值。因为这个模式依赖于2的幂,而这个模式依赖于找到最接近的2的幂并从那里开始,所以我提出以下解决方案。带上你的
模糊逻辑
伪代码示例(非优化)
//获得2的最近幂 for(变量i=0至60){ if(低位(2^i)=(2^i)){ 如果((2^i)<=低){ } 其他{ //找到电源:结束for循环 将i设置为61 } } //以2的幂自动1 将numOfBits设置为1 具有64个整数的正位的数组数字=0 将foundLOW设置为false 对于(var j=(2^功率)到高){ //在我们找到低值之前不要记录 如果(foundLOW为false)bitAND(j等于LOW){ 将foundLOW设置为true //如果j是奇数,则递增numOfBits 如果((1位和j)等于1){ 增量numOfBits } else if(j模4==0){ 相应地减少数字//请你自己解决这个问题 } //我们是下一个力量 增量功率 //重新开始模式 将numOfBits设置为1 } if(foundLOW等于true){ } } //从这里,导出K值。 |
5
0
您可以按以下方式有效地解决此问题:
功能
|
John V · 是否存在单元测试无法发现的逻辑/流错误类型? 6 年前 |
Beefster · 为什么ANSI颜色转义以“m”而不是“]”结尾? 6 年前 |
Guillermo Gutiérrez · STR转换是如何工作的? 7 年前 |
RudziankoÅ · 合并排序数组算法 7 年前 |
user8852560 · 构造函数中的验证和构造函数冲突 7 年前 |
jav974 · 订购产品时寻找最佳价格组合的算法 7 年前 |
hippietrail · 确定浮点数中前导零的数量 7 年前 |