指数b

时间:2016-10-18 09:40:09

标签: java math java-8 factorial

我编写了这段代码来查找指数b的最后一位数,但是SPOJ说错了。我尝试了几乎所有测试用例,但无法找到错误。 问题:http://www.spoj.com/problems/LASTDIG/ 我的解决方案:

package spoj;

import java.util.Scanner;

public class LastDigit {

    public static void main(String[] args) throws java.lang.Exception {
        Scanner p = new Scanner(System.in);
        for(int test = p.nextInt();test>0;test-- ){
            int a = p.nextInt();
            int b = p.nextInt();
            int result = (int) Math.pow(a,b);
            System.out.println(result%10);
        }
    }
}

8 个答案:

答案 0 :(得分:3)

Math.pow是一个浮点运算!它不会计算确切的结果。这就是为什么你在那里有那个有趣的演员。

因此,您需要使用BigInteger或编写自己的取幂函数。后者是更理想的,因为计算最后一个数字的更有效方式是减少模10,b模4,然后获取功率然后再次减少模10。这甚至应该在浮点运算精确的范围内工作。

另外:如果a % 10为负,你真的应该检查b是否是可逆的模10。否则,你将模数除以零的模10等效。

答案 1 :(得分:2)

我会建议一些可以解决这个问题的奇怪方法,作为一种有趣的事实,而不是应该使用的解决方案(至少我不会这样做)。认为它应该是)。

a0 < a <= 20,请查看这20个数字。

例如,点击6并查看结果:6, 36, 216, 1296, 7776...。看到?一切都以6结尾,因此这里很容易。

更难一个:19。结果:19, 361, 6859, 130321, 2476099...。看模式? 9, 1, 9, 1...

另一个只是为了展示:8, 64, 512, 4096, 32768, 262144...,因此模式为8, 4, 2, 6

基本上每个数字都有最后一位数的模式,你只需要从指数中取正确的模数,结果就在O(1)

数学人 - 请不要活着吃我。

答案 2 :(得分:1)

Math.pow适用于包含所有舍入错误的浮点数。因此,即使是中等大小ab的最后一位数也是错误的。

正如David Wallace的评论中提醒我的那样,更直接的错误是尝试将一个54 + 1位有符号整数(即使用double尾数提供的整数范围)拟合为31 + 1位有符号整数。对于小于舍入错误开始的数字的数字,会发生由于溢出引起的错误。可以通过使用long(int)数据类型来避免这种情况。

要获得正确的解决方案,您需要使用模幂运算,或找到a(或a%10)的最后一位数字的句点。

答案 3 :(得分:1)

package spoj;

import java.util.Scanner;

public class LastDigit {

public static void main(String[] args) throws java.lang.Exception {
    Scanner p = new Scanner(System.in);
    for(int test = p.nextInt();test>0;test-- ){

        int a = p.nextInt();
        int b = p.nextInt();
        System.out.println(LastDigit(a,b));

    }
}

public static int LastDigit(int a, int b) {
    int k,f=1;
    if(b==0)
        return 1;
    else {
        k =b%4;
        if(k==0)
            b=4;
        else
            b=k;
        for(int i=0;i<b;i++)
            f=f*a;

        return(f%10);
    }
}

}

这种方法运作正常。谢谢大家:))

答案 4 :(得分:0)

问题是你只需要最后一位数,所以你不需要知道最终结果。 。用的东西:

int r = (a * a) % 10;
    for (int n = 1; n < b - 1; n++){
        r *= a;
        r = r % 10;
    }

这很有效。给我一点时间,我会正确地解释。这是我认为的正确方法。

<强> [编辑]

好吧,我不是数学家(而且不是很擅长解释)所以没有证据,但举个例子:

4的智力,(4 * 4 * 4 * 4 ......)最后一位数将是4或6.如果你将16乘以4或6乘4,或者甚至是无关紧要的256乘4最后一位数将是4,重点是,您不需要整个值来跟踪最后一位数。我不知道怎么说,但想想:

3 * 7 = 21和

27 * 3 =(60 + 21)= 81。

对不起。可以解释得更好。我认为这是OP有望找到的解决方案。

答案 5 :(得分:0)

    import java.util.Scanner;

    public class LastDigit{

       public static void main(String []args){
        Scanner p = new Scanner(System.in);
        System.out.println("Enter a:");
        int a = p.nextInt();
        System.out.println("Enter b:");
        int b = p.nextInt();
        switch (a%10){
            case 0:case 1:case 5: case 6:
                System.out.println("Last digit is: "+a%10);    //if a ends with 0,1,5 or 6 a^b ends with 0,1,5 or 6 regardless what b is
                 break; 
            case 4:
                if(b%2==1){
                   System.out.println("Last digit is: "+4);     // if a ends with a 4 a^b ends with 4 if b is odd or ends with 6 if b is even                   
                }
               else{
                   System.out.println("Last digit is: "+6);
                }
                 break; 
            case 9:                                             
                if(b%2==1){
                    System.out.println("Last digit is: "+9);    // see case 4
                }
                else{
                   System.out.println("Last digit is: "+1);
                }
                 break; 
            case 2:
                if(b%4==1){                                         // if a ends with 2 a^b ends with 2,4,8 or 6 depending on what b%4 is
                   System.out.println("Last digit is: "+2);
                }
                if(b%4==2){
                    System.out.println("Last digit is: "+4);
                }
                if(b%4==3){
                    System.out.println("Last digit is: "+8);
                }
                else{
                     System.out.println("Last digit is: "+6);
                }
                 break; 
            case 3:
                if(b%4==1){                                         // if a ends wizh 3 a^b ends with 3,9,7 or 1 depending on what b%4 is
                  System.out.println("Last digit is: "+3);
                }
                if(b%4==2){
                  System.out.println("Last digit is: "+9);
                }
                if(b%4==3){
                  System.out.println("Last digit is: "+7);
                }
                else{
                  System.out.println("Last digit is: "+1);
                }
                break; 
            case 7:
                if(b%4==1){
                    System.out.println("Last digit is: "+7);
                }
                if(b%4==2){
                    System.out.println("Last digit is: "+9);
                }
                if(b%4==3){
                    System.out.println("Last digit is: "+3);
                }
                else{
                    System.out.println("Last digit is: "+1);
                }
                 break; 
            case 8: 
                if(b%4==1){
                    System.out.println("Last digit is: "+8);
                 }
                 if(b%4==2){
                    System.out.println("Last digit is: "+4);
                 }
                 if(b%4==3){
                    System.out.println("Last digit is: "+2);
                 }
                 else{
                     System.out.println("Last digit is: "+6);
                }
                 break;                 
        };
       }
    }

答案 6 :(得分:0)

这里是Kotlin函数,具有O(1)时间复杂度。这样只会计算出结果所需的最后一位。

具有整数幂的任何数字的最后一位数字都是周期性变化的,即,最后一位数字在某些步骤后会重复自身,并且对于任何数字都是固定的。

fun LastDigit(a: Int, b: Int): Int {
    var ld = a%10
    if(ld==0 || ld==1 || ld==5 || ld==6){
        return ld
    }
    if(ld==2 ){
        val n = b%4
        if(n==1)
            return 2
        if(n==2)
            return 4
        if(n==3)
            return 8
        if(n==0)
            return 6

    }
    if( ld==3){
        val n = b%4
        if(n==1)
            return 3
        if(n==2)
            return 9
        if(n==3)
            return 7
        if(n==0)
            return 1

    }
    if(ld ==7 ){
        val n = b%4
        if(n==1)
            return 7
        if(n==2)
            return 9
        if(n==3)
            return 3
        if(n==0)
            return 1

    }
    if(ld ==8 ){
        val n = b%4
        if(n==1)
            return 8
        if(n==2)
            return 4
        if(n==3)
            return 2
        if(n==0)
            return 6
    }

    if(ld==4){
        val n = b%2
        if(n==1)
            return 4
        if(n==0)
            return 6
    }
    if(ld==9){
        val n = b%2
        if(n==1)
            return 9
        if(n==0)
            return 1
    }
    return -1
}

答案 7 :(得分:-1)

您的代码正常工作正常:

Scanner p = new Scanner(System.in);
            for (int test = p.nextInt(); test > 0; test--) {
                int a = p.nextInt();
                int b = p.nextInt();
                int result = (int) Math.pow(a, b);
                System.out.println("Result:"+result);
                 System.out.println("Last Digit:"+result % 10);
            }

输出:

1

2

14

结果:1​​6384

最后一位数:4