目录
前言:
🐵准备去打蓝桥杯了,蓝桥杯主要考察算法,自己也会去刷一些往年的真题,在这里分享给大家。
时间显示
时间限制: 1.0 s 内存限制: 512.0 MB 本题总分:15 分
问题描述
小蓝要和朋友合作开发一个时间显示的网站。在服务器上,朋友已经获取了当前的时间,用一个整数表示,值为从 1970 年 1 月 1 日 00 : 00 到当前时刻经过的毫秒数。
现在,小蓝要在客户端显示出这个时间。小蓝不用显示出年月日,只需显示出时分秒即可,毫秒也不用显示,直接舍去即可。
给定一个用整数表示的时间,请将这个时间对应的时分秒输出。
输入格式
输入一行包含一个整数,表示时间。
输出格式
输出时分秒表示的当前时间,格式形如 HH:MM:SS ,其中 H 表示时,值为 0 00 到 23 ,MM 表示分,值为 0 到 59,S 表示秒,值为 0 到 59 。时、分、秒不足两位时补前导 0 。
测试用例
Input
:
46800999
Output :
13:00:00
Input
:
1618708103123
Output : 01:08:23
评测用例规模与约定
对于所有评测用例,给定的时间为不超过 10^18 。
题目分析
🎄给定的值是1970 年 1 月 1 日 00 : 00到一个时间的毫秒数,我们用这个毫秒数模上一天的毫秒数,结果就是不到一天中的总毫秒数。用这个总毫秒数除以一小时的毫秒数,结果就是这天内的小时数。用总毫秒数减这天的总小时的毫秒数,结果就是剩余总毫秒数。用剩余总毫秒数除以每分钟的毫秒数,结果就是不到一小时的分钟数。剩余总毫秒数减不到一小时的分钟数的毫秒数,结果就是不到一分钟的毫秒数,再将其换算为秒即可。
🎄最后将这些值按照题目约定连接起来,这里用的是StringBuilder,保证其字符串可以修改。
代码实现
public class Text1 {
public static String getTime(long t) {
//最后一天毫秒数
long endDayMs = t % (24 * 60 * 60 * 1000);
//小时数
long endDayH = endDayMs / (60 * 60 * 1000);
//剩余毫秒数
long tmp = endDayMs - endDayH * (60 * 60 * 1000);
//分钟数
long endDayM = tmp / (60 * 1000);
//剩余毫秒数
long tmp2 = tmp - endDayM * (60 * 1000);
//秒数
long endDayS = tmp2 / 1000;
StringBuilder str = new StringBuilder();
if(endDayH < 10) {
str.append('0');
str.append(endDayH);
str.append(':');
}else {
str.append(endDayH);
str.append(':');
}
if(endDayM < 10) {
str.append('0');
str.append(endDayM);
str.append(':');
}else {
str.append(endDayM);
str.append(':');
}
if(endDayS < 10) {
str.append('0');
str.append(endDayS);
}else {
str.append(endDayS);
}
return str.toString();
}
public static void main(String[] args) {
String str = getTime(1618708103123L);
System.out.println(str);
}
}
星期计算
问题描述
已知今天星期六,请问20^22后是星期几?注意用数字 1 到 7 表示星期一到星期日。
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
题目分析
🎈这道题比较容易理解,直接用20^22模上7,结果就是周六后的几天。取模结果为1,则答案为7。
山
问题描述
这天小明正在学数学。他突然发现有些正整数的形状像一座“山”,比如 123565321 、 145541 ,它们左右对称(回文)且数位上的数字先单调不减,后单调不增。小明数了很久也没有数完,他想让你告诉他在区间 [2022 , 2022222022] 中有多少个数的形状像一座“山”。
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
题目分析
😉直接遍历这个区间所有数字,在回文的情况下,需判断数位上的数字先单调不减,后单调不增。由于数字位数为奇数位和偶数位,增减区间是不相同的,需分开去判断。
代码实现
public class Test2 {
private static boolean isPalin(int a) {
int[] arr = new int[10];
int index = 0;
int count = 0;
while(a != 0) {
arr[index++] = (a % 10);
a /= 10;
count++;
}
int begin = 0;
int end = index - 1;
while(begin <= end) {
if(arr[begin] != arr[end]) {
return false;
}
begin++;
end--;
}
int mid = count >> 1;
if(count % 2 == 0) {
for (int i = 0; i < mid - 1; i++) {
if (arr[i] > arr[i + 1]) {
return false;
}
}
}else {
for (int i = 0; i < mid; i++) {
if (arr[i] > arr[i + 1]) {
return false;
}
}
}
return true;
}
private static int palinCount(int begin, int end) {
int count = 0;
for(int i = begin; i <= end; i++) {
if(isPalin(i)) {
System.out.println(i);
count++;
}
}
return count;
}
public static void main(String[] args) {
int a = 2022;
int b = 2022222022;
int count = palinCount(a, b);
System.out.println(count);
}
}
字符统计
时间限制 : 1.0s, 内存限制 : 512.0MB,本题总分: 10 分。
问题描述
给定一个只包含大写字母的字符串 S ,请你输出其中出现次数最多的字母。如果有多个字母均出现了最多次,按字母表顺序依次输出所有这些字母。
输入格式
一个只包含大写字母的字符串 S 。
输出格式
若干个大写字母,代表答案。
样例输入
BABBACAC
样例输出
AB
题目分析
🎉这里先统计每个字符的个数,然后将第一个字符入栈(假设它是最多的),接下来每次入栈都和栈顶元素比较一下,如果比它大,直接弹出栈内所有元素,这个元素入栈。和栈顶元素个数相等也要入栈,由于最多次字母可能有好几个。这样下来当统计的字符个数遍历完成后,栈内肯定存储字符个数最多的字符。由于最后需按照字符顺序输出字符,所以再利用一个栈倒数据。
代码实现
import java.util.Stack;
public class Main {
//利用栈
public static Stack<Character> CharacterStat(String str) {
int[] arr = new int[26];
for(int i = 0; i < str.length(); i++) {
arr[(str.charAt(i) - 'A')]++;
}
Stack<Character> stack = new Stack<>();
stack.push('A');
for(int i = 1; i < arr.length; i++) {
int tmp = stack.peek();
if(arr[i] > arr[tmp - 'A']) {
//直接清空栈
while(!stack.empty()) {
stack.pop();
}
stack.push((char)(i + 'A'));
}
if(arr[i] == arr[tmp - 'A']) {
stack.push((char)(i + 'A'));
}
}
return stack;
}
public static void main(String[] args) {
//由于顺序输出,利用栈倒数据
String str = "AAAAABBBBCCCCDDDDDDDDD";
Stack<Character> stack = CharacterStat(str);
Stack<Character> stack2 = new Stack<>();
while(!stack.empty()) {
stack2.push(stack.pop());
}
while(!stack2.empty()) {
System.out.println(stack2.pop());
}
}
}
最少刷题数
时间限制 : 1.0s,内存限制 : 512.0MB,本题总分:10 分。
问题描述
小蓝老师教的编程课有 N 名学生,编号依次是 1 . . . N 。第 i 号学生这学期刷题的数量是 A i 。对于每一名学生,请你计算他至少还要再刷多少道题,才能使得全班刷题比他多的学生数不超过刷题比他少的学生数。
输入格式
第一行包含一个正整数 N 。第二行包含 N 个整数: A 1 , A 2 , A 3 , . . . , A N 。
输出格式
输出 N 个整数,依次表示第 1 . . . N 号学生分别至少还要再刷多少道题。
样例输入
5
12 10 15 20 6
样例输出
0 3 0 0 7
评测用例规模与约定
对于 30 % 的数据, 1 ≤ N ≤ 1000 , 0 ≤ A i ≤ 1000 。
对于 100 % 的数据, 1 ≤ N ≤ 100000 , 0 ≤ A i ≤ 100000 。
题目分析
🪖遍历每一个同学的刷题数量,求得比它多刷题和少刷题的人数,如果符合要求直接输出0即可。不符合要求,让这位同学的刷题数量加1,然后再去求得比它多刷题和少刷题的人数,如果符合要求输出这位同学增加题目的数量,不符合就依次循环去判断(每次统计人数时需将自己跳过)。
代码实现
import java.util.Arrays;
public class Teas3 {
/**
* 统计比它多的学生数
* @param x
* @param arr
* @param n
* @return
*/
private static int more(int x, int[] arr, int n) {
int count = 0;
for(int i = 0; i < arr.length; i++) {
//不用比较自己
if(i == n) {
continue;
}
if(arr[i] > x) {
count++;
}
}
return count;
}
/**
* 统计比他少的学生数
* @param x
* @param arr
* @param n
* @return
*/
private static int less(int x, int[] arr, int n) {
int count = 0;
for(int i = 0; i < arr.length; i++) {
if(i == n) {
continue;
}
if(arr[i] < x) {
count++;
}
}
return count;
}
public static int[] doExerciseCount(int n, int[] arr) {
int[] ret = new int[n];
for(int i = 0; i < arr.length; i++) {
int more = more(arr[i], arr, i);
int less = less(arr[i], arr, i);
int count = 1;
while(more > less) {
more = more(arr[i] + count, arr, i);
less = less(arr[i] + count, arr, i);
count++;
}
ret[i] = count - 1;
}
return ret;
}
public static void main(String[] args) {
int n = 5;
int[] arr = {12,10,15,20,6};
int[] ret = doExerciseCount(n, arr);
System.out.println(Arrays.toString(ret));
}
}
小结:
🐵在思考问题时,需要将各种情况都要考虑进去,还需特别注意边界的控制。