时间限制:3000 ms | 内存限制:65535 KB
难度:1
描述
输入一个自然数K(K>1),如果存在自然数M和N(M>N),使得K^M和K^N均大于等于1000,且他们的末尾三位数相等,则称M和N是一对“K尾相等数”。下面请编程求出M+N最小的K尾相等数。
输入
第一行包含一个正整数T,T<10000,表示有T组数据;
随后有N行,每行包括一个整数K(K<2*10^10);
输出
对于输入的每个整数K,输出对应的M+N的最小值;
样例输入
1
2
样例输出
难度:1
描述
输入一个自然数K(K>1),如果存在自然数M和N(M>N),使得K^M和K^N均大于等于1000,且他们的末尾三位数相等,则称M和N是一对“K尾相等数”。下面请编程求出M+N最小的K尾相等数。
输入
第一行包含一个正整数T,T<10000,表示有T组数据;
随后有N行,每行包括一个整数K(K<2*10^10);
输出
对于输入的每个整数K,输出对应的M+N的最小值;
样例输入
1
2
样例输出
120
这是一道很有意思的题。虽然难度是1.但是通过寻找好的答案,也学到了很多,特地在此总结下。
一开始我的思路:首先1、用BigInteger肯定是正解,2、对1000取余,然后用个数组保存下来3、循环遍历是否相同
没做出来后:分析问题:首先是超时严重。因为输入一个大数后,乘法运算要好久。
其次、如何判断M和N是最小,一开始考虑的循环遍历肯定不行了。
正确思路:发现一些小的东西。我只要对后3未数进行乘法运算就好。例如2 当2大于1000时势1024 取024也就是24 然后24*2=48 ;48取余1000是48;48再乘2
依次,这样就解决了数据过大导致超时问题。
如何判断M和N相加最小?
我看了网上的答案,发现用一个1000范围的int类型数组。因为对1000取余后,他余数的范围是0~999.所以看代码就ok
static BigInteger aa;
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
aa = new BigInteger(sc.nextInt()+"");
BigInteger a2=new BigInteger(aa.toString()+"");
int test=0;
test=recursion(aa);
int[] a=new int[1000];
int c2=Integer.parseInt(aa.mod(BigInteger.valueOf(1000)).toString());
a[c2]=test;
aa=BigInteger.valueOf(c2);
for(int b=0;b<=10000;b++){
aa=a2.multiply(aa);
aa=aa.mod(BigInteger.valueOf(1000));
System.out.println(aa);
test++;
int num=Integer.parseInt(aa.toString());
if(a[num]==0){
a[num]=test;
}else{
System.out.println(a[num]+test);
break;
}
}
}
public static int recursion(BigInteger big){
BigInteger big2=new BigInteger("1000");
BigInteger big3=new BigInteger(big.toString());
int test=1;
if(big.compareTo(big2)<=0){
for(;big.compareTo(big2)<=0;){
test++;
big=big3.multiply(big);
}
}
aa=big;
return test;
}