前言
本文章是对第十四届蓝桥杯JavaB组题目写的题解,代码均经过测试,但存在部分非更优解,故请酌情参考。
试题A:阶乘求和
思路一:
阶乘问题一般是分解因子,而根据本题条件的隐喻可知,阶乘中必然有大部分数据无需计算,那么如何定位需要计算的数据与不需要计算的数据就十分重要。而又因为因子中2x5=10,那么1 000 000 000有几个零,就要有几对2x5,这样的阶乘和必然后九位全为0,换句话说这样的阶乘就不需要考虑到计算中,摸索到这个规律后,我们只需要找到这个数字就可以了。经过一顿乱造可得,n!=90!时刚好是这个区分线,所以我们只需要计算1!+...+90!即可。
思路二:
我们可以正常求解,并加入判断只要数字取余1 000 000 000后的结果为0时,停止累加计算即可。
public class test {
public static void main(String[] args) {
long max = 202320232023L;
long last = 1000000000;
long a = 1;
long b = 0;
for (int i = 1; i <= max; i++) {
//求出每个数的阶乘的后九位
a = (a * i) % last;
//当此处的条件成立时,说明运算出的数的阶乘的后九位已经全部为0,就可以停止运算输出结果了
if (a % last == 0) {
System.out.println(b);
return;
} else {
//求运算到目前为止的所有数的阶乘之和的后九位
b = (b % last + a % last) % last;
}
}
}
}
试题B:幸运数字
思路:
没什么好说的,按照题目要求进行筛选即可。在这里浅浅的分析下时间复杂度,首先按照题意可知要找第2023个幸运数字,那也就是说我们需要从1开始对他进行“幸运数”判断,而每个数要跑4个进制的check,所以时间复杂度应该是O(n^2)。
根据下图的数量级变化曲线可知,大概率可以算出,故不做优化处理直接干。
import java.math.BigInteger;
/**
* Lucky Number
* 第2023个应该是215040
*/
public class T2 {
public static void main(String[] args) {
long i = 1;
int theNum = 0;
while(true){
if(check(BigInteger.valueOf(i))){
++theNum;
}
if(theNum == 2023){
System.out.println(i);
return;
}
++i;
}
}
public static boolean check(BigInteger num){
String num2 = num.toString(2);//转成二进制字符串
String num8 = num.toString(8);
String num10 = num.toString(10);
String num16 = num.toString(16);
BigInteger num2add = BigInteger.ZERO;
for (int i = 0; i < num2.length(); ++i) {
num2add = num2add.add(new BigInteger(num2.charAt(i) + "", 2));
}
if (num.mod(num2add).compareTo(BigInteger.ZERO) != 0) {
return false;
}
BigInteger num8add = BigInteger.ZERO;
for(int i=0; i <num8.length(); ++i){
num8add = num8add.add(new BigInteger(num8.charAt(i)+"",8));
}
if(num.mod(num8add).compareTo(BigInteger.ZERO)!=0){
return false;
}
BigInteger num10add = BigInteger.ZERO;
for(int i=0; i <num10.length(); ++i){
num10add = num10add.add(new BigInteger(num10.charAt(i)+"",10));
}
if(num.mod(num10add).compareTo(BigInteger.ZERO)!=0){
return false;
}
BigInteger num16add = BigInteger.ZERO;
for(int i=0; i < num16.length();++i){
num16add = num16add.add(new BigInteger(num16.charAt(i)+"",16));
}
if(num.mod(num16add).compareTo(BigInteger.ZERO)!=0){
return false;
}
return true;
}
}