第十四届蓝桥杯大赛——真题训练第11天
Posted 小卢先冲
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第十四届蓝桥杯大赛——真题训练第11天相关的知识,希望对你有一定的参考价值。
目录
第一题:蓝肽子序列_求最长公共子序列
题目描述
L 星球上的生物由蛋蓝质组成,每一种蛋蓝质由一类称为蓝肽的物资首尾连接成一条长链后折叠而成。
生物学家小乔正在研究 L 星球上的蛋蓝质。她拿到两个蛋蓝质的蓝肽序列,想通过这两条蓝肽序列的共同特点来分析两种蛋蓝质的相似性。
具体的,一个蓝肽可以使用 1 至 5 个英文字母表示,其中第一个字母大写,后面的字母小写。一个蛋蓝质的蓝肽序列可以用蓝肽的表示顺序拼接而成。
在一条蓝肽序列中,如果选取其中的一些位置,把这些位置的蓝肽取出,并按照它们在原序列中的位置摆放,则称为这条蓝肽的一个子序列。蓝肽的子序列不一定在原序列中是连续的,中间可能间隔着一些未被取出的蓝肽。
如果第一条蓝肽序列可以取出一个子序列与第二条蓝肽序列中取出的某个子序列相等,则称为一个公共蓝肽子序列。
给定两条蓝肽序列,找出他们最长的那个公共蓝肽子序列的长度。
输入描述
输入两行,每行包含一个字符串,表示一个蓝肽序列。字符串中间没有空格等分隔字符。
其中有 ,两个字符串的长度均不超过 10001000。
输出描述
输出一个整数,表示最长的那个公共蓝肽子序列的长度。
输入输出样例
示例
输入
LanQiaoBei LanTaiXiaoQiao
输出
2
运行限制
- 最大运行时间:1s
- 最大运行内存: 128M
题目分析
(1)字符串切割(存储每个以大写字母为开头的单词)
(2)最长公共子序列问题(LCS)
- 最长公共子序列我们需要分别遍历字符串S1和字符串S2
- 遍历比较的时候只会出现两种情况:字符串相等或字符串不等
- 对应这两种状态分别给出两种dp状态转移方程:
相等:dp[i][j]=dp[i-1][j-1]+1
不相等:dp[i][j]=max(dp[i-1][j],dp[i][j-1])dp[i][j]的表示含义:字符串S1的前i个字符和字符串S2的前j个字符可以构成最长公共子序列为:dp[i][j]
参考原文链接:https://blog.csdn.net/m0_55858611/article/details/129783258
题目代码
import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class 蓝肽子序列 public static void main(String[] args) Scanner sca = new Scanner(System.in); String s1 = sca.next(); String s2 = sca.next(); char[] chars1 = s1.toCharArray(); char[] chars2 = s2.toCharArray(); ArrayList<String> list1 = new ArrayList<>(); ArrayList<String> list2 = new ArrayList<>(); int temp = 0; //切割字符串 for (int i = 1; i < chars1.length; i++) if (chars1[i] >= 'A' && chars1[i] <= 'Z') list1.add(s1.substring(temp, i)); temp = i; //当最后一个单词为大写时 if (i == chars1.length - 1) list1.add(chars1[i] + ""); //当最后一个单词为小写时 else if (i == chars1.length - 1) list1.add(s1.substring(temp, s1.length())); temp = 0; //切割字符串 for (int i = 1; i < chars2.length; i++) if (chars2[i] >= 'A' && chars2[i] <= 'Z') list2.add(s2.substring(temp, i)); temp = i; if (i == chars2.length - 1) list2.add(chars2[i] + ""); else if (i == chars2.length - 1) list2.add(s2.substring(temp, s2.length())); //最长公共子序列 int[][] dp = new int[list1.size() + 1][list2.size() + 1]; for (int i = 1; i <= list1.size(); i++) for (int j = 1; j <= list2.size(); j++) if (list1.get(i - 1).equals(list2.get(j - 1))) dp[i][j] = dp[i - 1][j - 1] + 1; else dp[i][j] = Math.max(dp[i][j - 1], dp[i - 1][j]); System.out.println(dp[list1.size()][list2.size()]);
第二题: 时间显示
题目描述
小蓝要和朋友合作开发一个时间显示的网站。
在服务器上,朋友已经获取了当前的时间,用一个整数表示,值为从 1970 年 11 月 11 日 00:00:00 到当前时刻经过的毫秒数。
现在,小蓝要在客户端显示出这个时间。小蓝不用显示出年月日,只需要显示出时分秒即可,毫秒也不用显示,直接舍去即可。
给定一个用整数表示的时间,请将这个时间对应的时分秒输出。
输入描述
输入一行包含一个整数,表示时间。
输出描述
输出时分秒表示的当前时间,格式形如
HH:MM:SS
,其中HH
表示时,值为 0 到 23,MM
表示分,值为 0 到 59,S
表示秒,值为 0 到 59。时、分、秒 不足两位时补前导 0。输入输出样例
示例 1
输入
46800999
输出
13:00:00
示例 2
输入
1618708103123
输出
01:08:23
评测用例规模与约定
对于所有评测用例,给定的时间为不超过 10181018 的正整数。
运行限制
- 最大运行时间:1s
- 最大运行内存: 512M
题目分析
该题有两种方法可解:
1. 使用Java自带的API进行计算
* 思路: 将输入的毫秒数创建为Date日期对象,使用SimpleDateFormat设置为"HH:mm:ss"的格式
如果想输出其他格式,我们可以任意转换,比如:
SimpleDateFormat ft = new SimpleDateFormat ("HH-mm-ss");
Date date = new Date(mills) mils只能是毫秒数 计算从
1970-01-01 08:00:00开始经过了mils毫秒后的时间为多少
- * 难点: Date类 SompleDateFormat类的使用
2. 通过计算毫秒数,将范围确定为一天内,并按照题意忽略毫秒位,计算出其所代表的时间。1秒等于1000毫秒
题目代码
方法一:
import java.sql.Date; import java.text.SimpleDateFormat; import java.util.Scanner; // 1:无需package // 2: 类名必须Main, 不可修改 public class Main public static void main(String[] args) /* * 思路: 将输入的毫秒数创建为Date日期对象,使用SimpleDateFormat设置为"HH:mm:ss"的格式 * 难点: Date类 SompleDateFormat类的使用 */ Scanner sc = new Scanner(System.in); long mills = sc.nextLong(); //这里剪去8个小时的时间是因为这里的Date是以1970-01-01 08:00:00开始的 //比题目中要求的时间早8个小时,所以要剪去。 mills -= 8 * 60 * 60 * 1000; Date date = new Date(mills); SimpleDateFormat ft = new SimpleDateFormat("HH:mm:ss"); System.out.println(ft.format(date));
方法二:
import java.util.Scanner; public class 时间显示 public static void main(String[] args) Scanner sca = new Scanner(System.in); long n = sca.nextLong(); //当天剩余的秒数 1s==1000ms long miao = n / 1000 % (24 * 60 * 60); long HH = miao / 3600; //当时那一小时的分钟为 long MM = miao % 3600/60; long SS = miao % 3600%60; StringBuilder sBuilder = new StringBuilder(); if (HH < 10) sBuilder.append("0" + HH + ":"); else sBuilder.append("" + HH + ":"); if (MM < 10) sBuilder.append("0" + MM + ":"); else sBuilder.append("" + MM + ":"); if (SS < 10) sBuilder.append("0" + SS); else sBuilder.append("" + SS); // String str = sBuilder.toString(); System.out.println(sBuilder);
第三题:顺子日期
问题描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
小明特别喜欢顺子。顺子指的就是连续的三个数字:123、456 等。顺子日期指的就是在日期的 yyyymmdd 表示法中,存在任意连续的三位数是一个顺子的日期。
例如 20220123 就是一个顺子日期,因为它出现了一个顺子:123; 而 20221023 则不是一个顺子日期,它一个顺子也没有。
小明想知道在整个 2022 年份中,一共有多少个顺子日期?
运行限制
- 最大运行时间:1s
- 最大运行内存: 512M
题目分析
1)使用Calendar日期类
2)将日期转为字符串进行判断是否为顺子日期
题目代码
import java.util.Calendar; public class 顺子日期 public static void main(String[] args) Calendar cal = Calendar.getInstance(); cal.set(2022, 0, 1); Calendar cal2 = Calendar.getInstance(); cal2.set(2023, 0, 1); int res = 0; while (cal.before(cal2)) int year = cal.get(Calendar.YEAR); int month = cal.get(Calendar.MONTH); int day = cal.get(Calendar.DAY_OF_MONTH); String temp = year + ""; if (month < 9) temp += "0" + (month + 1);//特别注意这里的月份是从0-11所以我们要加1 else temp += (month + 1); if (day < 10) temp += "0" + day; else temp += day; //判断是否为顺子日期 for (int i = 0; i < temp.length() - 1; i++) int count = 0;//每次换一个数都要吧原先的计数器清0 int a = Integer.parseInt(temp.charAt(i) + ""); for (int j = i + 1; j < temp.length(); j++) int b = Integer.parseInt(temp.charAt(j) + ""); if (++a == b) count++; if (count == 2) res++; // System.out.print(temp+" "); 当不确定答案的时候可以打印出来看看 break; else break; if (count == 2) break; cal.add(Calendar.DATE, 1);//将日期加1 System.out.println(res);
第十四届蓝桥杯三月真题刷题训练——第 8 天
目录
第 1 题:分数
题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
1/1+1/2+1/4+1/8+⋯
每项是前一项的一半,如果一共有 20 项,求这个和是多少,结果用分数表示出来。
类似:3/2,当然,这只是加了前 2 项而已。分子分母要求互质。
运行限制
- 最大运行时间:1s
- 最大运行内存: 128M
代码:
package 第十四届蓝桥杯三月真题刷题训练.day8;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
/**
* @author yx
* @date 2023-03-11 12:09
*/
public class 分数
static PrintWriter out =new PrintWriter(System.out);
static BufferedReader ins=new BufferedReader(new InputStreamReader(System.in));
static StreamTokenizer in=new StreamTokenizer(ins);
/**
* 输入
* in.nextToken()
* int a= (int)in.nval;
*
* 输出
* out.print();
* out.flush();
*/
public static void main(String[] args)
/*
等比数列公式
Sn=a1*(1-q^n)/(1-q)
按题目意思,a1=1,n=20,q=1/2
带入得到:
Sn=(2^n-1)/2^(n-1)
*/
out.println((int) Math.pow(2,20)-1+"/"+(int) Math.pow(2,19));
out.flush();
第 2 题:回文日期
题目描述
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≤89991231,保证 N 是一个合法日期的 8 位数表示。
输出描述
输出两行,每行 1 个八位数。第一行表示下一个回文日期,第二行表示下一个 ABABBABA 型的回文日期。
输入输出样例
示例
输入
20200202
输出
20211202 21211212
运行限制
- 最大运行时间:1s
- 最大运行内存: 256M
代码:
我这题为了偷懒少考虑了一些情况的(闰年和每个月份对应的日子是不同的)
oj居然没检测出来,哈哈哈!!
package 第十四届蓝桥杯三月真题刷题训练.day8;
import java.io.*;
/**
* @author yx
* @date 2023-03-11 12:18
*/
public class 回文日期
static PrintWriter out =new PrintWriter(System.out);
static BufferedReader ins=new BufferedReader(new InputStreamReader(System.in));
static StreamTokenizer in=new StreamTokenizer(ins);
/**
* 输入
* in.nextToken()
* int a= (int)in.nval;
*
* 输出
* out.print();
* out.flush();
*/
public static void main(String[] args) throws IOException
in.nextToken();
int n=(int) in.nval;
boolean huiWen=false;
boolean aB=false;
while (true)
n++;
if(isHeFa(n))
if(isHuiWem(n)&&!huiWen)
out.println(n);
huiWen=true;
if(isAB(n))
out.println(n);
out.flush();
return;
static boolean isHuiWem(int n)
char[] arr=(n+"").toCharArray();
int l=0;
int r=7;
while (l<=r)
if(arr[l]!=arr[r])return false;
l++;
r--;
return true;
static boolean isAB(int n)
char[] arr=(n+"").toCharArray();
if(arr[0]==arr[2]&&arr[0]==arr[5]&&arr[0]==arr[7]&&arr[1]==arr[3]&&arr[1]==arr[4]&&arr[1]==arr[6])
return true;
return false;
static boolean isHeFa(int n)
String s= n+"";
/**
* 下面的日期判断都是渣渣
*/
if(Integer.parseInt(s.substring(4,6))>=1&&Integer.parseInt(s.substring(4,6))<=12)
// if(isRunYear(Integer.parseInt(s.substring(0,4)))&&Integer.parseInt(s.substring(4,6))==2)
// if(Integer.parseInt(s.substring(6,8))>=1&&Integer.parseInt(s.substring(6,8))<=29)
// return true;
//
//
if(Integer.parseInt(s.substring(6,8))>=1&&Integer.parseInt(s.substring(6,8))<=31)
return true;
return false;
// static boolean isRunYear(int n)
// int year=Integer.parseInt((n+"").substring(0,4));
// /*
// 闰年的两种情况:
// 1、100年整的只能被400整除
// 2、非100年整的只能被4整除,不能被100整除
// */
// if(year%400==0||(year%100!=0&&year%4==0))
// return true;
//
// return false;
//
第 3 题:迷宫
跑个步回来补题
代码:
以上是关于第十四届蓝桥杯大赛——真题训练第11天的主要内容,如果未能解决你的问题,请参考以下文章