如果数字x的任何两个连续数字的总和在k和2k之间,则给定数字x是“好”。 我需要找到一个算法,对于给定的数字k和给定的数字n,找到有多少'好'的n位数字。
我在PHP中实现了这个,但复杂性很大(我正在搜索所有那些'好'的数字并计算它们,因此复杂度为O(10 ^ n))。
<?php
$n = 5;
$k = 5;
$min = $k*1;
$max = $k*2;
$counter = 0;
for ($i = pow(10, $n-1); $i<pow(10,$n); $i++)
{
$number = $i;
$prev = $number % 10;
$number = $number / 10;
while($number >= 10)
{
$crnt = $number % 10;
$number = $number / 10;
if ( ($crnt+$prev) > $min AND ($crnt+$prev) < $max ) {
echo "good number: $i\n";
$counter++;
}
$prev = $crnt;
}
}
echo "counter: ".$counter."\n";
?>
有人可以确认我是否可以解决这个问题:
n=100 // given
k=10 // given
counter = 0;
for(i=10; i<100; i++)
{
if( (i/10)+(i%10) > k ) && ( (i/10)+(i%10) < 2*k )
counter++;
}
total = counter^(n-1)
答案 0 :(得分:2)
对pow
的所有电话肯定都没有帮助。
您可以做的是对所有“好”的两位数字进行映射。完成映射后,您需要做的就是检查数字中的每对数字是否正常。您可以通过连续除以10和模100来完成此操作。
这样的事情可以解决问题,前提是你没有给它一个负数,假设你已经设置了$good
数组。
function isgood( $num ) {
while( $num >= 100 && $good[$num%100] ) {
$num /= 10;
}
return $good[$num%100];
}
下一个最明显的事情是记住更大的序列。这是一种动态编程原理。我们已经通过存储2位序列的“优点”来记忆小序列。但你可以很容易地使用它们来生成3,4,5,6位的序列...无论你的可用内存允许什么。使用您已有的备忘录来生成一个额外数字的序列。
因此,如果您为最多5位数字建立了备忘录,那么每次除以1000,并获得极大的加速。
答案 1 :(得分:1)
查找n
位数和最高位数d
的“不好数字”的数量是一个简单的动态编程问题。
10^n
是“好数字”加上“不好数字”的数量。
我不会给你更多的帮助。
答案 2 :(得分:0)
您的算法计算 NOT 良好的2位数整数。然后它将此值返回到n - 1
的幂。这应该可以得到不好的n
个数字。如果从n
数字整数的总量中减去此值,您应该得到您想要的结果。或者我们可以通过改变标志来避免这样做:
for($i=10; $i<100; $i++) {
if( ($i/10) + ($i%10) > $k && ($i/10) + ($i%10) < 2*$k ) {
$cnt++;
}
}
$result = pow($cnt, $n-1);
这应该可以得到好的n
数字整数,但让我们看看是否真的如此。
好吧,cnt
会给出好2位整数的数量。因此,在前两个位置,我们可以放置cnt
中的任何一个:
0 1 2 3 4 5 ...
x y
那么,第1和第2位呢?那么,位置1由第一个位置固定。
0 1 2 3 4 5 ...
x y
y z
所以我们必须证明cnt
有z
种可能性,我不明白为什么会出现这种情况,所以我会说算法错了。你的算法可能会超额计算。