我编写了这段代码来查找指数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);
}
}
}
答案 0 :(得分:3)
Math.pow
是一个浮点运算!它不会计算确切的结果。这就是为什么你在那里有那个有趣的演员。
因此,您需要使用BigInteger
或编写自己的取幂函数。后者是更理想的,因为计算最后一个数字的更有效方式是减少模10,b模4,然后获取功率然后再次减少模10。这甚至应该在浮点运算精确的范围内工作。
另外:如果a % 10
为负,你真的应该检查b
是否是可逆的模10。否则,你将模数除以零的模10等效。
答案 1 :(得分:2)
我会建议一些可以解决这个问题的奇怪方法,作为一种有趣的事实,而不是应该使用的解决方案(至少我不会这样做)。认为它应该是)。
a
为0 < 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
适用于包含所有舍入错误的浮点数。因此,即使是中等大小a
和b
的最后一位数也是错误的。
正如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
结果:16384
最后一位数:4