此题单为算法基础精选题单,包含蓝桥杯常考考点以及各种经典算法,可以帮助你打牢基础,查漏补缺。
本题单目标是冲击蓝桥杯省一国一,团体程序天梯赛个人国三、XCPC区域赛铜/银奖
前言
本次题单重点关注日期问题,进制转换问题,排序问题,其中日期问题和进制转换问题,几乎是必考题,几乎每年蓝桥杯都能看到,大家需要重点掌握。
日期问题:蓝桥杯热门考点,基本每年省赛必考。
进制转换问题:与日期一样蓝桥杯热门考点,基本每年省赛必考。
模拟题(暴力题):蓝桥杯也叫暴力杯,只要暴力打的多,省一照样可以轻松拿,所以模拟题也是蓝桥杯必练的题目。
目录
一、日期问题题目:
1.特殊日期
2.回文日期
3.日期问题
二、进制转换问题题目:
1.有趣的二进制
2.穿越时空之门
3.九进制转十进制
4.acwing 3452进制转换
三、常见的排序问题
快速排序模板题
四、模拟题(暴力)
1.字符金字塔
2.增高防护塔
3.零钱兑换
特殊日期 ——原题
题目
对于一个日期,我们可以计算出年份的各个数位上的数字之和,也可以分别计算月和日的各位数字之和。请问从 19001900 年 11 月 11 日至 99999999 年 1212 月 3131 日,总共有多少天,年份的数位数字之和等于月的数位数字之和加日的数位数字之和。
例如,20222022 年 1111 月 1313 日满足要求,因为 2+0+2+2=(1+1)+(1+3)2+0+2+2=(1+1)+(1+3) 。
请提交满足条件的日期的总数量。
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
LocalDate date=LocalDate.of(2000, 1, 1);
int ans=0;
while(true){
int year=date.getYear();
int mon=date.getMonthValue();
int day=date.getDayOfMonth();
if(year==2000000&&mon==1&&day==1)break;
if(year%mon==0&&year%day==0){
ans++;
System.out.println(date+"");
}
date=date.plusDays(1);
}
System.out.println(ans+1);
//System.out.print(35813062+1);
}
}
回文日期 ——原题
题目描述
2020 年春节期间,有一个特殊的日期引起了大家的注意:2020 年 2 月 2 日。因为如果将这个日期按 “yyyymmdd” 的格式写成一个 8 位数是 20200202,恰好是一个回文数。我们称这样的日期是回文日期。
有人表示 20200202 是 “千年一遇” 的特殊日子。对此小明很不认同,因为不到 2 年之后就是下一个回文日期:20211202 即 2021 年 12 月 2 日。
也有人表示 20200202 并不仅仅是一个回文日期,还是一个 ABABBABA 型的回文日期。对此小明也不认同,因为大约 100 年后就能遇到下一个 ABABBABA 型的回文日期:21211212 即 2121 年 12 月 12 日。算不上 “千年一遇”,顶多算 “千年两遇”。
给定一个 8 位数的日期,请你计算该日期之后下一个回文日期和下一个 ABABBABA 型的回文日期各是哪一天。
输入描述
输入包含一个八位整数 NN,表示日期。
对于所有评测用例,10000101≤N≤8999123110000101≤N≤89991231,保证 NN 是一个合法日期的 8 位数表示。
输出描述
输出两行,每行 1 个八位数。第一行表示下一个回文日期,第二行表示下一个 ABABBABA 型的回文日期。
输入输出样例
示例
输入
20200202
输出
20211202
21211212
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
static int x=0,y=0;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int data = sc.nextInt();
for (int i = data+1; i <= 99999999&&y==0; i++) {
String str = i + "";
int i1=(str.charAt(4)-'0')*10 + str.charAt(5)-'0',i2 = (str.charAt(6)-'0')*10 + str.charAt(7)-'0';
if (i1 > 12 || i2 > 31 || i1 == 0 || i2 == 0)
continue;
char[] ch = str.toCharArray();
huiwenriqi(ch);
}
sc.close();
}
public static void huiwenriqi(char[]ch) {
char a = ch[0], b = ch[1], c = ch[2], d = ch[3],e = ch[4],f = ch[5],g = ch[6],h = ch[7];
if(a==h&&b==g&&c==f&&d==e&&x==0) {
System.out.println(ch);x=1;
}
if(a==c&&c==f&&f==h&&b==d&&d==e&&e==g) {
System.out.println(ch);y=1;
}
}
}
日期问题 ——原题
题目描述
小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在 1960 年 1 月 1 日至 2059 年 12 月 31 日。令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。
更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。
比如 02/03/04,可能是 2002 年 03 月 04 日、2004 年 02 月 03 日或 2004 年 03 月 02 日。
给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?
输入描述
一个日期,格式是 "AA/BB/CCAA/BB/CC" (0≤A,B,C≤90≤A,B,C≤9)。
输出描述
输出若干个不相同的日期,每个日期一行,格式是 "yyyy−MM−ddyyyy−MM−dd"。多个日期按从早到晚排列。
输入输出样例
示例
输入
02/03/04
输出
2002-03-04
2004-02-03
2004-03-02
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
String[] res=new Scanner(System.in).nextLine().split("/");
int a=Integer.parseInt(res[0]),b=Integer.parseInt(res[1]),c=Integer.parseInt(res[2]);
for (int i = 1960; i <=2059; i++) {
for (int j = 1; j <=12 ; j++) {
int n=30;
if (j==1||j==3||j==5||j==7||j==8||j==10||j==12){
n=31;
}else if (j==2){
if ((i%4==0&&i%100!=0)||i%400==0){
n=29;
}else {
n=28;
}
}
for (int k = 1; k <=n ; k++) {
if (a==i%100&&b==j&&c==k||a==j&&b==k&&c==i%100||a==k&&b==j&&c==i%100){
System.out.printf("%d-%02d-%02d\n",i,j,k);
}
}
}
}
}
}
有趣的二进制——原题
小新在学C语言的时候,邝老师告诉他double类型的数据在表示小数的时候,小数点后的有效位是有限的,但是没有告诉他这是为什么,后来他发现0.1的二进制是一个无限循环小数0.000110011001100110011001100···,如果只取27位小数,再转换成十进制的话就变成了0.09999999403953552,小新开心的解决了这个问题。与此同时,小新又有了一个新的问题:一个数在64位二进制补码表示下,一共有多少个1。因为小数有无解的情况,所以我们保证输入的都是整数。
输入描述:
有多组数据,每一行为一个数字n。
输出描述:
输出这个数字在二进制补码下1的个数。
示例1
输入
15
输出
4
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNextLong()) {
long a = in.nextLong();
int n = Long.bitCount(a);
System.out.println(n);
}
}
}
穿越时空之门——原题
问题描述
随着 20242024 年的钟声回荡,传说中的时空之门再次敞开。这扇门是一条神秘的通道,它连接着二进制和四进制两个不同的数码领域,等待着勇者们的探索。
在二进制的领域里,勇者的力量被转换成了力量数值的二进制表示中各数位之和。
在四进制的领域里,力量的转换规则相似,变成了力量数值的四进制表示中各数位之和。
穿越这扇时空之门的条件是严苛的:当且仅当勇者在二进制领域的力量等同于四进制领域的力量时,他才能够成功地穿越。
国王选定了小蓝作为领路人,带领着力量值从 11 到 20242024 的勇者们踏上了这段探索未知的旅程。作为小蓝的助手,你的任务是帮助小蓝计算出,在这 20242024 位勇者中,有多少人符合穿越时空之门的条件。
答案提交
这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int count = 0;
for(int i=1;i<=2024;i++) {
int ans = 0;
String power2 = Integer.toString(i, 2);
String power4 = Integer.toString(i, 4);
if (Ans(power2)==Ans(power4)) {
count++;
}
}
System.out.println(count);
}
public static int Ans(String str) {
int ans = 0;
for(int i=0;i
九进制转十进制——原题
问题描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
九进制正整数 (2022)9(2022)9 转换成十进制等于多少?
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String rs="2022";
System.out.println(Integer.parseInt(rs,9));
scan.close();
}
}
3452. 进制转换 - AcWing题库
写出一个程序,输入一个十六进制的数值字符串,输出该数值的十进制字符串。
输入格式
输入包含多组测试数据。
每组数据占一行,包含一个十六进制的数值字符串。
输出格式
每组数据输出一行结果,表示给定数值的十进制字符串。
数据范围
每个输入最多包含 100100 组数据。
所有答案均在 int 范围内。
输入样例:
0xA
输出样例:
10
import java.util.*;
import java.math.*;
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
int x=0;
String str=sc.next();
char[] c=str.toCharArray();
if(c[0]=='0')x=Integer.parseInt(str.substring(2),16);
else if(c[0]=='-')x=-1*Integer.parseInt(str.substring(3),16);
else x=Integer.parseInt(str,16);
System.out.println(x);
}
}
}
实现快速排序 - 蓝桥云课
给定你一个长度为 nn 的整数数列。
请你使用快速排序对这个数列按照从小到大进行排序。
并将排好序的数列按顺序输出。
输入格式
输入共两行,第一行包含整数 n。
第二行包含 n 个整数(所有整数均在 1∼1091∼109 范围内),表示整个数列。
输出格式
输出共一行,包含 n 个整数,表示排好序的数列。
数据范围
1≤n≤1000001≤n≤100000
输入样例:
5
3 1 2 4 5
输出样例:
1 2 3 4 5
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main{
public static void main(String[] args) throws IOException{
Scanner sc=new Scanner(System.in);
int num = sc.nextInt();
int[] arr = new int[num];
for (int i = 0; i < num; i++) {
arr[i] = sc.nextInt();
}
quickSort(arr, 0, num - 1);
for (int i = 0; i < num; i++) {
System.out.print(arr[i] + " ");
}
}
public static void quickSort(int[] q, int l, int r) {
if (l >= r) return;
int x = q[l+r>>1];
int i = l - 1;
int j = r + 1;
while (i < j) {
do i++; while (q[i] < x);
do j--; while (q[j] > x);
if (i < j) {
int temp = q[i];
q[i] = q[j];
q[j] = temp;
}
}
quickSort(q, l, j);
quickSort(q, j + 1, r);
}
}
字符金字塔 ——原题
请打印输出一个字符金字塔,字符金字塔的特征请参考样例
输入描述:
输入一个字母,保证是大写
输出描述:
输出一个字母金字塔。
输入
C
输出
A ABA ABCBA
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
char ch = sc.next().charAt(0);
int n=ch-'A'+1;
for(int i=1;i<=n;i++){
int index=1;
for(int j=0;j=(2*i-1)/2+1){
System.out.print((char)('A'+j-1-index));
index+=2;
}
else
System.out.print((char)('A'+j));
}
System.out.println();
}
}
}
增高防护塔——原题
题目描述
牛村村口有一排防护塔,建的越高防护范围越广。
牛可乐被村长安排去建塔,他每天的工作是给连续的几个塔都建高X米,请问等他工作了m天以后每个防护塔的高度分别是多少?
输入描述:
第一行输入一个整数n,表示防护塔的数量。 第二行输入n个数,表示每个防护塔的初始高度。 第三行输入一个整数m,表示牛可乐的工作天数。 接下来m行每行三个整数a,b,c,表示给第a个塔到第b个塔增建c的高度。 1 <= n,m <= 100, 1 <= a, b <= n, 1 <= c <= 1000
输出描述:
输出一行,包含n个整数,以空格隔开,表示各个防护塔最终的高度。
示例1
输入
4 1 2 3 4 3 1 2 1 2 3 1 4 4 1
输出
2 4 4 5
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc =new Scanner(System.in);
int n =sc.nextInt();
int [] first_high= new int[n];
for(int s=0;s
零钱兑换——原题
题目描述
n元人民币换成1元、2元、5元的零钱,请计算共有多少种兑换方法?
输入描述:
输入一行,包含一个整数n 1 <= n <= 200
输出描述:
输出一行,包含一个整数
输入
100
输出
541
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int sum = 0;
for (int i = 0; 5*i <= n; i++) {
for (int j = 0; 2*j <= n; j++) {
for (int k = 0; k <= n; k++) {
if(5*i+2*j+k==n)sum++;
}
}
}
System.out.println(sum);
}
}