这题可以直接用double来做,考的时候我还在想会不会爆精度,后来发现答案也是对的。
此题直接对7求余即可。
public class Main {
public static void main(String[] args) {
double res = Math.pow(20, 22);
res %= 7;
System.out.println(res + 6);
}
}
不放心的话也可以转成 BigInteger来做
贴一下BigInteger的代码
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
BigInteger bg = new BigInteger(20+"");
BigInteger res = bg.pow(22).remainder(BigInteger.valueOf(7)).add(BigInteger.valueOf(6));
System.out.println(res);
}
}
试题 B:【填空题】
题目:
答案:3138
这题我知道很多人把题目都给看错了,我认识好几个都是只看到了回文,没看到还有单调的条件。(大佬们都忙着做后面的题)
解析:读题可以知道,回文数左右对称,所以只需判断是否回文,然后再判断左边的数单调不减,则右边的数一定单调不增。
可以节约一点时间,但即使这样我考试这题也跑了一分多钟hh..
public class Main {
public static void main(String[] args) {
long start = System.currentTimeMillis();
int count = 0;
for (int i = 2022; i <= 2022222022; i++) {
if (isPalindrome(i) && check(i)) {
count++;
}
}
long end = System.currentTimeMillis();
System.out.println(count);
System.out.println("共用时" + (end - start) / 1000 % 60 + "秒");//测了一下时间用时40s
}
private static boolean check(int num) {
String s = num + "";
for (int i = 0; i < s.length() / 2; i++) {
if (s.charAt(i) > s.charAt(i + 1)) return false;
}
return true;
}
private static boolean isPalindrome(int num) {
String n = num + "";
StringBuilder sb = new StringBuilder(n);
sb.reverse();
for (int i = 0; i < n.length(); i++) {
if (sb.charAt(i) != n.charAt(i)) return false;
}
return true;
}
}
这题好像不转成字符串处理会快一点,下次再研究一下。
试题 C:字符统计【编程题】 题目: 解析:签到题,分别统计输出即可。
import java.util.Scanner;
public class C {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
int[] arr = new int[26];
for (int i = 0; i < s.length(); i++) {
arr[s.charAt(i) - 'A']++;
}
int max = Integer.MIN_VALUE;
for (int i = 0; i < 26; i++) {
max = Math.max(max, arr[i]);
}
for (int i = 0; i < 26; i++) {
if(arr[i] == max) System.out.print((char) (i+'A'));
}
}
}
试题 D:最少刷题数【编程题】
题目:
解析:
这个题我觉得虽然是个十分题,但是还是挺难的(也可能是我太菜了)。主要是要考虑的因素比较多,核心的想法应该是要计算出左边、右边与中间相等的数的个数,分情况判断每个数加上最小刷题数与中间数相等后需不需要+1。
这题当时给我做烦了,浪费了很多时间,我只考虑了和中间的相比,比它大就输出0,比它小就输出中间的数减去num[i]+1,并没有判断左右数与中间数相等的情况,没有全部AC。这里贴一下别人的代码
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] nums = new int[n];
int[] temp = new int[n];
for (int i = 0; i < n; i++) {
nums[i] = sc.nextInt();
temp[i] = nums[i];
}
// 排序数组
Arrays.sort(temp);
// 中间的下标
int midIndex = n / 2;
// 中间的值
int midValue = temp[midIndex];
int midOption = 0;
int option = 0;
// 左边和中值相同值的数量
int sameLeft = 0;
// 右边和中值相同值的数量
int sameRight = 0;
for (int i = midIndex - 1, j = midIndex; i >= 0; i--, j++) {
if (temp[i] == midValue) {
sameLeft++;
}
if (temp[j] == midValue) {
sameRight++;
}
if (temp[i] != temp[j]) {
break;
}
}
if (sameLeft >= sameRight) {
option = 1;
}
if (sameLeft > sameRight) {
midOption = 1;
}
for (int i = 0, len = nums.length; i < len; i++) {
int count = 0;
if (nums[i] == midValue) {
count = midOption;
} else {
count = midValue - nums[i] + option;
if (count < 0) {
count = 0;
}
}
if (i != n - 1) {
System.out.print(count + " ");
} else {
System.out.println(count);
}
}
}
}
我觉得这个代码的方法还是比较巧妙的hh
试题 E: 求阶乘 题目: 解析这题我又给想简单了,此题的数据范围非常大,所以可能只能过极个别样例。也不能直接从1到N枚举判断,突破口是数字中谁和谁相乘得到10,很容易想到2*5,2的个数肯定比5多,所以N的阶乘最后有多少0 就看N能分成多少5 。可以从1~N每个数都除以5,然后统计个5的个数,因为25/5也会得到5,所以需要用循环计算。
这里也是贴一下大佬们的代码
暴力法
import java.util.Scanner;
public class Main {
//后面以0 结尾的一定是5!....(5的倍数的阶乘) 所以只需要判断5的倍数的阶乘
//(判断的数)/5 就是含有5的个数 也是阶乘后0的个数
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long k = sc.nextLong();
long count;
long a = 5;//直接从5的阶乘(120)开始判断
while (true) {
long tempA = a;
count = 0;
while (tempA > 0) {
tempA /= 5;
count += tempA;
}
if (count < k) {
a += 5;
} else if (count == k) {
System.out.println(a);
break;
} else {
System.out.println(-1);
break;
}
}
}
}
二分法
//因为k的值很大 不可能用枚举的思想依次对k比较
//我们先测一下 Long.MAX_VALUE的阶乘后边有多少个0
//Long.MAX_VALUE的阶乘后边有 2305843009213693937个0(10的19次方) > k
//Long.MAX_VALUE/2的阶乘后边有 1152921504606846964个0(10的19次方) > k
(所有在使用二分法时 有边界是Long.MAX_VALUE-5 左边界是1 不会有溢出)
//因为N的阶乘后边有k个0 这个k随N的增大而增大 所以我们用二分查找
//对于 100% 的数据,1 ≤ K ≤ 10的18次方
//把l = 1作为最左边 r = Long.MAX_VALUE - 5;做为最右边
import java.util.Scanner;
public class Main {
// 求x的阶乘后边有多少个0
static long calc(long x){
long res = 0;
while (x!=0){
res = res+x/5;
x/=5;
}
return res;
}
//
static void solve() {
//第1部分代码
//System.out.print(calc(10));//计算10的阶乘是不是后边有2个0
//System.out.print(calc(25));//计算25的阶乘是不是后边有6个0
//第2部分代码
//System.out.print(calc(Long.MAX_VALUE/2 ));
//Long.MAX_VALUE的阶乘后边有 2305843009213693937个0
//Long.MAX_VALUE/2的阶乘后边有 1152921504606846964个0
//二分查找
Scanner scanner = new Scanner(System.in);
long k = scanner.nextLong();
long l = 1, r = Long.MAX_VALUE - 5;//l为最左边 r为最右边
//long l = 1, r = 20;//方便学习可以debug
while (l < r) {
long mid = (l + r) / 2;
if (k <= calc(mid)) {//如果mid的阶乘的0数大于等于k
r = mid;//我们让r变为mid (可以等于mid)
} else {//如果mid的阶乘的0数小于k
l = mid + 1; //我们让l变为mid+1(大于mid,所以可以+1)
//并且这里想让while循环中止就要不得不+1
}
}
//二分法 l是最后的答案
if (calc(r) != k) {
System.out.println(-1);
} else {
System.out.println(r);
}
}
public static void main(String[] args) throws Exception{
//System.out.println((Long.MAX_VALUE + 1)/2);
// 大于Long.MAX_VALUE 会变成负数 所以有必要改进
solve();
}
}
陆续更新,敬请期待.......
试题 F: 最大子矩阵 题目:解析: 试题 G:数组切分 题目:
解析: 试题 H: 回忆迷宫 题目: 解析: 试题 I: 红绿灯 题目:
解析: 试题 J: 拉箱子 题目:
解析:



