Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
2的有趣功能-算法/数学(来自Hackerrank ACM APC)_C_Algorithm_Math - Fatal编程技术网

2的有趣功能-算法/数学(来自Hackerrank ACM APC)

2的有趣功能-算法/数学(来自Hackerrank ACM APC),c,algorithm,math,C,Algorithm,Math,我在最近的一次比赛中遇到了一个问题。 我无法找到解决方案,目前还没有关于这个问题的社论 我在这里引用问题陈述,以防链接不起作用 查找大于或等于A且小于或等于B的整数n的数量(A编程竞赛中经常发生的情况我提出了一个启发式方法,我没有证明,但似乎是合理的。我编写了一个简短的程序来查找最大1000000的数字,它们是: 36 736 8736 48736 948736 因此,我的理论是:每个连续数字都有前一个数字的后缀,只增加一个数字。希望这能让你找到正确的解决方法。请注意,如果我的假设是正确的,

我在最近的一次比赛中遇到了一个问题。 我无法找到解决方案,目前还没有关于这个问题的社论

我在这里引用问题陈述,以防链接不起作用


查找大于或等于A且小于或等于B的整数n的数量(A编程竞赛中经常发生的情况我提出了一个启发式方法,我没有证明,但似乎是合理的。我编写了一个简短的程序来查找最大1000000的数字,它们是:

36
736
8736
48736
948736
因此,我的理论是:每个连续数字都有前一个数字的后缀,只增加一个数字。希望这能让你找到正确的解决方法。请注意,如果我的假设是正确的,你只需要查找150个数字,而查找每个连续数字需要检查可能添加的9个数字

对于类似问题的一般建议-总是尝试找到前几个数字,并思考一些关系

在一场比赛中,经常会出现这样的情况:你提出了一个类似于我上面提出的理论,但没有时间证明它。你没有时间证明它。只希望你是对的,并编写代码

编辑:我相信我能够证明我的上述猜测(事实上,我遗漏了一些数字——见文章末尾)。首先让我指出,v3ga在评论中指出,上述算法一直工作到
75353432948736
,因为没有任何数字可以让新数字变得“有趣”根据你给出的定义。然而,我完全错过了另一个选项-你可以预先添加一些数字0,然后添加一个非零数字

现在我将证明一个引理:

引理:如果a1a2…an是一个有趣的数字,n大于3,那么a2…an也是有趣的

证明: 2a1a2…an=2a1*10n-1*2a2a2…an

现在我将证明2a1*10n-1*2a2a2…an与2a2a2…模10n-1相当

为此,让我们证明2a1*10n-1*2a2a2…an-2a2a2…an可被10n-1整除

2a1*10n-1*2a2a2…an-2a2a2…an= 2A2…an*(2a1*10n-1-1) A2A2…An对于我们考虑的值大于n-1。

因此,剩下来证明用10n-1除差的就是5n-1除2a1*10n-1-1。
为此,我将使用欧拉定理:

2phi(5n-1)=1(模5n-1)

现在phi(5n-1)=4*(5n-2),对于n>=34*(5n-2)将除以a1*10n-1(实际上甚至仅仅是10n-1)

因此2a1*10n-1给出模5n-1的余数1,因此5n-1除以2a1*10n-1-1

因此,10n-1将2a2a2…an*(2a1*10n-1-1)除以,因此2a2a2a2…an和2a2a3a4…an的最后n-1位是相同的

现在,由于a1a2a2…an是有趣的,2a1a2a2…an的最后n位是a1a2a2…an,因此2a2a3a4…an的最后n-1位是a2a3a4…an,因此a2a3a4…an也是有趣的。QED


使用这个引理,您将能够解决这个问题。请注意,您也可以预先添加一些零,然后添加一个非零数字。

在20个增量后,最后的数字开始重复。因此,对于任何带有最后数字1的n,答案的最后数字将是2。因此,大多数n值可以立即消除

2^1=2
2^21=2097152
2^101=2535301200456458802993406410752

2^2=4
2^22=4194304
2^42=439804651104

事实上,只有两种可能共用最后一个数字:

2^14=16384
2^16=65536

2^34=17179869184
2^36=68719476736


如果n是14+20x或16+20x,那么它可能会工作,因此您需要检查它。否则,它将无法工作。

我对此类问题不是很在行。但模幂运算似乎是您的关键。 对A到B范围内的所有n重复此操作:
1.查找k,n中的位数。这可以在O(logn)中完成
2.使用模幂运算找到2^n(mod 10^k),并检查它是否等于n。这需要O(n)个时间。(实际上,O(n)个乘法)

编辑
事实上,不要对每个n重复整个过程。给定2^n(mod 10^k),我们可以在恒定时间内找到2^(n+1)(mod 10^k)。利用这个事实进一步加速

编辑-2
这不适用于如此大的范围。

一般来说,您可以通过在输出中找到一些模式来尝试解决这些问题。我们的团队在比赛中接受了这个问题。我们的方法是在满足标准的值中找到一个通用模式。如果您打印前几个这样的数字,那么您将找到以下模式

    36
   736
  8736
 48736
948736
因此,948736之后的下一个数字应该是7位数字,可以是1948736、2948736、3948736、4948736、5948736、6948736、7948736、8948736、9948736中的任意一位。因此,请检查哪个值有效,您就有了下一个数字。继续以这种方式,您可以返回自己获得所有150个数字

但这里有一个问题。将“1”添加到“9”后,会有一些数字不会立即跟随上一个数字。要解决此问题,您现在可以开始添加从10到99的值,然后检查是否有有效数字。如果仍然没有有效数字,请再次尝试添加从100到999的数字

现在使用这种方法,您将获得满足问题中给出的标准的所有137个值,并轻松回答所有查询。例如,显示了实现这一点的工作java代码。它将打印所有137个值

import java.io.*;
import java.math.*;
import java.util.*;

class Solution
{ 

    public static void main(String[] args)throws java.lang.Exception{
        new Solution().run();
    }

    void run()throws java.lang.Exception{
        BigInteger[] powers = new BigInteger[152];
        powers[0] = one;
        for(int i=1; i<=150; i++){
            powers[i] = powers[i-1].multiply(ten);
        }
        BigInteger[] answers = new BigInteger[152];
        answers[2] = BigInteger.valueOf(36);
        answers[3] = BigInteger.valueOf(736);

        int last = 3;
        for(int i=4; i<=150; i++){
            int dif = i-last;
            BigInteger start = ten.pow(dif-1);
            BigInteger end = start.multiply(ten);
            while(start.compareTo(end) < 0){
                BigInteger newVal = powers[last].multiply(start);
                newVal = newVal.add(answers[last]);
                BigInteger modPow = pow(two, newVal, powers[i]);
                if(modPow.equals(newVal)){
                    answers[i] = newVal;
                    System.out.println(answers[i]);
                    last = i;
                    break;
                }
                start = start.add(one);
            }
        }
    }


    BigInteger pow(BigInteger b, BigInteger e, BigInteger mod){
        if(e.equals(zero)){
            return one;
        }
        if(e.mod(two).equals(zero)){
            BigInteger x = pow(b, e.divide(two), mod);
            x = x.multiply(x).mod(mod);
            return x;
        }else{
            BigInteger x = pow(b, e.divide(two), mod);
            x = x.multiply(x).mod(mod);
            x = x.multiply(two).mod(mod);
            return x;
        }
    }

    BigInteger ten = BigInteger.valueOf(10);
    BigInteger zero = BigInteger.ZERO;
    BigInteger one = BigInteger.ONE;
    BigInteger two = BigInteger.valueOf(2);
}
import java.io.*;
导入java.math.*;
导入java.util.*;
类解决方案
{ 
公共静态void main(字符串[]args)引发java.lang.Exception{
新解决方案().run();
}
void run()抛出java.lang.Exception{
BigInteger[]幂=新的BigInteger[152];
幂[0]=1;

对于(inti=1;i这是一个非常有趣的性质。在比赛中,我发现36是最重要的
36
736
8736
48736
948736
    36
   736
  8736
 48736
948736
import java.io.*;
import java.math.*;
import java.util.*;

class Solution
{ 

    public static void main(String[] args)throws java.lang.Exception{
        new Solution().run();
    }

    void run()throws java.lang.Exception{
        BigInteger[] powers = new BigInteger[152];
        powers[0] = one;
        for(int i=1; i<=150; i++){
            powers[i] = powers[i-1].multiply(ten);
        }
        BigInteger[] answers = new BigInteger[152];
        answers[2] = BigInteger.valueOf(36);
        answers[3] = BigInteger.valueOf(736);

        int last = 3;
        for(int i=4; i<=150; i++){
            int dif = i-last;
            BigInteger start = ten.pow(dif-1);
            BigInteger end = start.multiply(ten);
            while(start.compareTo(end) < 0){
                BigInteger newVal = powers[last].multiply(start);
                newVal = newVal.add(answers[last]);
                BigInteger modPow = pow(two, newVal, powers[i]);
                if(modPow.equals(newVal)){
                    answers[i] = newVal;
                    System.out.println(answers[i]);
                    last = i;
                    break;
                }
                start = start.add(one);
            }
        }
    }


    BigInteger pow(BigInteger b, BigInteger e, BigInteger mod){
        if(e.equals(zero)){
            return one;
        }
        if(e.mod(two).equals(zero)){
            BigInteger x = pow(b, e.divide(two), mod);
            x = x.multiply(x).mod(mod);
            return x;
        }else{
            BigInteger x = pow(b, e.divide(two), mod);
            x = x.multiply(x).mod(mod);
            x = x.multiply(two).mod(mod);
            return x;
        }
    }

    BigInteger ten = BigInteger.valueOf(10);
    BigInteger zero = BigInteger.ZERO;
    BigInteger one = BigInteger.ONE;
    BigInteger two = BigInteger.valueOf(2);
}
def powm(i):
j = 10
a = 1
while i:
    if i % 2:
        a = a * j
    i /= 2
    j *= j
return a


def power(n, i):
    m = powm(i)
    y = 1
    x = 2
    while n:
        if n % 2 == 1:
            y = y * x % m
        x = x * x % m
        n /= 2
    return y

mylist = []
mylist.append(power(36, 2))
n = mylist[0]
print(n)
for i in range(3, 170):
    p = power(n, i)
    print p
    if p != n:
        mylist.append(p)
        n = p

t = input()
while t:
    x = raw_input().split(" ")
    a = int(x[0])
    b = int(x[1])
    i = 0
    #while i <= 150:
        #print mylist[i]
        #i += 1
#print power(8719476736,14)

while mylist[i] < a:
    i += 1
ans = 0
while mylist[i] <= b:
    i += 1
    ans += 1
print ans
t -= 1