试题A:星期计算
本题总分:5 分
【问题描述】
已知今天是星期六,请问 20^{22}天后是星期几?注意用数字 1 到 7 表示星期一到星期日。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
思路与题解
A题显然是个签到题,很多人第一思路就是“取余”,思路没错,但是如果直接暴力取余,那你就格局小了,哥们!
因为20的22次幂(大于288)明显不在long类型的范围内【(263)-1】,那么就要分步骤做取余运算:
根据公式: (a * b) % p = (a % p * b % p) % p
20^22相当于22个20做了21次乘法运算,所以我的思路是把每一次乘法的结果取余,这样,别说是long可以装得下,就算是int也手拿把掐了!
public static void Java_B_A(){
int n = 20;
for(int i=0;i<21;i++)
n = (20*n)%7;
System.out.println((n+5)%7+1);
}
最终结果:7 ,即星期日。
试题B:山
本题总分:5 分
【问题描述】
这天小明正在学数数。他突然发现有些正整数的形状像一座“山”,比如 123565321、145541,它们左右对称(回文)且数位上的数字先单调不减,后单调不增。
小明数了很久也没有数完,他想让你告诉他在区间 [2022, 2022222022] 中有多少个数的形状像一座“山”。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
思路与题解
直接暴力遍历,并判断条件,时间有点长但好用。
public static void Java_B_B(){
int sum = 0;
for(int i=2022;i<=2022222022;i++) {
if(isUp(i)&&isMirror(i)) {
sum++;
}
}
System.out.println(sum);
}
public static boolean isMirror(int num){
StringBuffer str = new StringBuffer(num+"");
if((str.toString()).equals(str.reverse().toString()))
return true;
return false;
}
public static boolean isUp(int num){
String st=num+"";
int len=st.length()%2==0?st.length()/2:st.length()/2+1;
for(int i=1;i<len;i++) {
if(st.charAt(i)<st.charAt(i-1)) {
return false;
}
}
return true;
}
最终结果:3138 。
试题C:字符统计
时间限制: 1.0s 内存限制: 512.0MB 本题总分:10 分
【问题描述】
给定一个只包含大写字母的字符串 S ,请你输出其中出现次数最多的字母。如果有多个字 母均出现了最多次,按字母表顺序依次输出所有这些字母。
【输入格式】
一个只包含大写字母的字符串 S .
【输出格式】
若干个大写字母,代表答案。
【样例输入】
BABBACAC
【样例输出】
AB
【评测用例规模与约定】
对于 100% 的评测用例,1 ≤ |S | ≤ .
思路与题解
本题运用Java的集合框架很容易解决。首先遍历字符串,把其中的每一种字母以键值对<字母种类,出现次数>的形式保存到HashMap中,然后遍历map提取出出现次数最多的n个字母,把它们存到list列表中,利用Collections工具类把list中字母排序,最后输出打印。
public static void Java_B_C(){
Scanner scanner = new Scanner(System.in);
String input = scanner.next();
HashMap<Character, Integer> mp = new HashMap();
for(int i=0;i<input.length();i++){
char ch = input.charAt(i);
if (mp.get(ch) != null)
mp.put(ch, (mp.getOrDefault(ch, 0)) + 1);
else
mp.put(ch, 1);
}
int maxNum = Integer.MIN_VALUE;
List<Character> list = new ArrayList<Character>();
for(Character c:mp.keySet()){
if(mp.get(c)>=maxNum){
maxNum = mp.get(c);
list.add(c);
}
}
Collections.sort(list);
for(Character ch:list){
System.out.print(ch);
}
}
试题D:最少刷题数
时间限制: 1.0s 内存限制: 512.0MB 本题总分:10 分
【问题描述】
小蓝老师教的编程课有 N 名学生,编号依次是 1 . . . N。第 i 号学生这学期刷题的数量是 。
对于每一名学生,请你计算他至少还要再刷多少道题,才能使得全班刷题比他多的学生数不 超过刷题比他少的学生数。
【输入格式】
第一行包含一个正整数 N。
第二行包含 N 个整数: ,. . . , .
【输出格式】
输出 N 个整数,依次表示第 1 . . . N 号学生分别至少还要再刷多少道题。
【样例输入】
5
12 10 15 20 6
【样例输出】
0 3 0 0 7
【评测用例规模与约定】
对于 30% 的数据,1 ≤ N ≤ 1000, 0 ≤ ≤ 1000.
对于 100% 的数据,1 ≤ N ≤ 100000, 0 ≤ ≤ 100000.
思路与题解
对输入的刷题数进行排序;
分情况考虑:奇数情况下,超过中间值才能满足全班刷题比他多的学生数不超过刷题比他少的学生数;偶数情况下需要等于中间偏大的值就可以满足条件。
public static void Java_B_D() {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int[] nums = new int[n];
int[] count = new int[n];
for (int i = 0; i < nums.length; i++) {
// 输入的一个数组,并把这个数组复制下来
nums[i] = scan.nextInt();
count[i] = nums[i];
}
// 个数组排一下序方便找到较中间的那个数
Arrays.sort(count);
// 找到中间的索引
int index = 0;
// 分情况讨论值
if (n % 2 == 0) {
index = n / 2 + 1;
} else {
index = n / 2;
}
// 找到中间值
int middle = count[index];
for (int i = 0; i < n; i++) {
// 判断得到最终结果
if (nums[i] < middle) {
System.out.print(middle - nums[i] + 1);
System.out.print(" ");
} else {
System.out.print(0);
System.out.print(" ");
}
}
}