我觉得还是好好掌握简单题,并总结一下题目的类型和知识点。因为我太菜了
借鉴别人的知识点蓝桥杯历年真题分类汇总(史上最全版本,一定不要错过)-CSDN博客
日期与时间问题,枚举(但是一般不会单着考,会结合set,map,最大公约数等) ,数学+思维+找规律,动态规划,字符串,全排列,最大公约数 ,排序(二分查找,快排,分治思想), DFS,BFS。最近几年会发现蓝桥杯题目越来越难,少了许多'暴力’,偏向于动态规划和数学思维,这种题目一般都是不简单的,不过没关系,填空题前几道还是比较偏向枚举的考察,不过要结合着set去重,二分查找,map,等技巧考,做几道真题就可以掌握八九不离十,、其次就是日期问题,还是屡见不鲜,我们可以借助excel和电脑自带计算器做.简单的题做对拿个省三是没问题的.其次就是要掌握一些回溯算法可以看我这篇博客回溯算法,实在不会做直接暴力搜索,可以得到部分分.还有就是全排列,最大公约数和最小公倍数,set去重,vector,map等STL容器.sort,max等algorithm等库里的常用函数,字符串和整数切换,大数相乘等技巧和模板要多记记,竞赛中很常见这样基本稳省二了.最后说一下,有余力的同学可以学一下DP算法,可以看一下这个视频DP分析法学会之后可以准备国赛了。
2023年
题目一 阶乘求和
【问题描述】
令 S = 1! + 2! + 3! + ... + 202320232023! ,求 S 的末尾 9 位数字。提示:答案首位不为 0 。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一
个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
看到这么大的数字,想到用大数类BigInteger.仔细看题,要求S的末尾9位数字,那么极有可能这后9位比较特殊。
求阶乘:
int sum = 0;
int j = 1;
for(int i = 1; i <= 2; i++) {
j = j+i;// j = j * i;
sum += j;
}
System.out.println(sum);
大数类:
创建对象:
BigInteger big = new BigInteger("202320232023");
BigInteger big1 = BigInteger.valueOf(2023);//括号里式int或long型,不能超出范围
在for循环里面,我们要写i< 202320232023时,会出错,因为i时整形的,所以这里不能写202320232023,我们想到把i也转换成大数类,但是没有办法表示<,.....当我们不知道怎么办的时候,在读题,发现只要求末尾9位数字即可,猜想可能到某个数的阶乘之和之后末尾的九位数已经不再改变,所以开始尝试算阶乘,注意:用上面的求阶乘的z只能算到25的阶乘和,27的阶乘和就超过了整数的范围,所以我们要记住:40!以及40以后的阶乘后9位都是0.
所以,我们只需要算前39的阶乘和就可算出202320232023的阶乘和的末尾9位数字啦,然后我们用大数套用算阶乘的代码
大数中的运算:前提a和b得都是大数
加 a.add(b)
减 a.subtract(b)
乘 a.multiply(b)
除 a.divide(b)
取模 a.mod(b)
比较大小 a.compareTo(b) a>b,返回正数,a<b,返回负数,a=b,返回0;
BigInteger.valueOf(i);可以将整数i转化成大数类型
代码:
package lan2023;
import java.math.BigInteger;
public class A阶乘求和 {
public static void main(String[] args) {
BigInteger sum = new BigInteger("0");
BigInteger j = new BigInteger("1");
for(int i = 1; i <= 39; i++) {
j = j.multiply(BigInteger.valueOf(i));
sum = sum.add(j);
}
System.out.println(sum);
}
}
运行结果: 20935051082417771847631371547939998232420940313
答案:420940313
题目二:幸运数字
【问题描述】
哈沙德数是指在某个固定的进位制当中,可以被各位数字之和整除的正整数。例如 126 是十进制下的一个哈沙德数,因为 (126) 10 mod (1+2+6) = 0 ; 126也是八进制下的哈沙德数,因为 (126) 10 = (176) 8 , (126) 10 mod (1 + 7 + 6) = 0 ;同时 126 也是 16 进制下的哈沙德数,因为 (126) 10 = (7 e ) 16 , (126) 10 mod (7 +e ) = 0 。小蓝认为,如果一个整数在二进制、八进制、十进制、十六进制下均为哈沙德数,那么这个数字就是幸运数字,第 1 至第 10 个幸运数字的十进制表示为: 1 , 2 , 4 , 6 , 8 , 40 , 48 , 72 , 120 , 126 . . . 。现在他想知道第2023 个幸运数字是多少?你只需要告诉小蓝这个整数的十进制表示即可。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
要找到第2023个幸运数字,我们想到可以用遍历直到找到第2023个幸运数字为止,在for循环里进行判断是时候,我们需要求当前遍历数的二进制、八进制、十进制、十六进制,此时我们可以编写一个方法来帮我们计算一下某个数的进制数各位和,注意不是求进制是几,我们需要传入两个参数当前的数,以及转换成几进制的,
package lan2023;
public class B幸运数字 {
public static void main(String[] args) {
int count = 0;
int i = 1;
for(i = 1; ; i++) {
if(i % f(i,2) == 0 &&i % f(i,8) == 0 &&i % f(i,16) == 0 &&i % f(i,10) == 0) {
count++;
}
if(count == 2023) {
break;
}
}
System.out.println(i);
}
public static int f(int n, int jin) {
int sum = 0;
while(n > 0) {
sum += n % jin;
n = n / jin;
}
return sum;
}
}
运行结果:215040
注意:
1.转换成几进制的时候,对所要转换的数 不断地除jin,n = n / jin;而不是n/10,这个是去掉个位
2.在if的判断里面忘记写i%f(i,10) == 0
3.我最开始想的是用for循环,让i小于一个非常大的数,后面尝试i<100000根本不哦那个写,就能运行,当我们不知道循环的结束条件时一般用while
还有用while循环的
package lan2023;
public class B幸运数字 {
public static void main(String[] args) {
int count = 0;
int i = 1;
while(true) {
if(i % f(i,2) == 0 && i % f(i,8) == 0 && i % f(i,16) == 0 && i % f(i, 10) == 0) {
count ++;
}
if(count == 2023) {
break;
}
i++;
}
System.out.println(i);
}
public static int f(int n, int jin) {
//求进制就是要不断地除进制数然后取余
int num = 0;
while(n > 0) {
num += n % jin;
n = n / jin;
}
return num;
}
}
题目三:数组分割
【题目描述】
小蓝有一个长度为 N 的数组 A = [A0, A1,…, AN−1]。现在小蓝想要从 A 对应的数组下标所构成的集合 I = {0,1, 2, . . . , N − 1} 中找出一个子集 R1,那么 R1在 I 中的补集为 R2。记S1=∑r∈R1Ar,S2=∑r∈R2Ar,我们要求 S1 和 S2 均为偶数,请问在这种情况下共有多少种不同的 R1。当 R1 或 R2 为空集时我们将 S1 或 S2 视为 0。
【输入格式 】
第一行一个整数T,表示有 T 组数据。 接下来输入 T 组数据,每组数据包含两行:第一行一个整数 N,表示数组A 的长度;第二行输入 N 个整数从左至右依次为 A0, A1, . . . , AN−1,相邻元素之间用空格分隔。
【输出格式】对于每组数据,输出一行,包含一个整数表示答案,答案可能会很大,你需要将答案对1000000007 进行取模后输出。
【样例输入】
2
2
6 6
2
1 6
【样例输出】
4
0
【提示】
对于第一组数据,答案为 4。(注意:大括号内的数字表示元素在数组中的下标。)
R1 = {0}, R2 = {1};此时 S1 = A0 = 6 为偶数, S2 = A1 = 6 为偶数。
R1 = {1}, R2 = {0};此时 S1 = A1 = 6 为偶数, S2 = A0 = 6 为偶数。
R1 = {0, 1}, R2 = {};此时 S1 = A0 + A1 = 12 为偶数, S2 = 0 为偶数。
R1 = {}, R2 = {0, 1};此时 S1 = 0 为偶数, S2 = A0 + A1 = 12 为偶数。
对于第二组数据,无论怎么选择,都不满足条件,所以答案为 0。对于 20% 的评测用例,1 ≤ N ≤ 10。
对于 40% 的评测用例,1 ≤ N ≤ 10^2。
对于 100% 的评测用例,1 ≤ T ≤ 10, 1 ≤ N ≤ 10^3 , 0 ≤ Ai ≤ 10^9。
其实就是把数组A分成地两部分R1、R2,这两部分地元素之和都是偶数,现在就是要找有多少中这种分法。既然要找和都为偶数的,我们可以先找A中有多少个偶数(even个),有多少个奇数(odd个),然后R1在里面选,剩下的就是R2的,所以我们可以只需要知道R1是怎么选的。
那么对于偶数选几个,奇数选几个,也是有条件的,偶数可以随便选几个都行,但是奇数只能有偶数个,否则和将不会得到偶数。偶数中的选法 2*2*2*2...*2(乘even次,有选和不选两种情况),奇数中选法,C(0,0) = 1,C(2,0)+C(2,2)=2,C(4,0)+C(4,2)+C(4,4)=8,(只考虑偶数个)
所以偶数的选法:2^even种;奇数的选法:2^(odd-1)种。
具体步骤:
先输入有几组数据,针对每组数据,我们进行判断,判断完一组后,我们将减少一组要判断的。对于某组数据,我们先输入这组的长度,以及元素,判断奇数偶数的个数,如果奇数有奇数个,直接输出0,表示没有这样的组合满足条件,如果奇数有偶数个或0个,则进行相应的操作。
package lan2023;
import java.util.Scanner;
public class C数组分割 {
public static int mod = 1000000007;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] a;
while(n>0) {
int m = sc.nextInt();
a = new int[m];
for(int i = 0; i < m; i++) {
a[i] = sc.nextInt();
}
int even = 0, odd = 0;
for(int i = 0; i < m; i++) {
if(a[i] % 2 == 0) {
even ++;
}else {
odd ++;
}
}
if(odd % 2 != 0) System.out.println(0);
else {
int c= 1;
if(odd==0) odd = 1;//当奇数为0个时,将其置1,防止even + odd -1小于even
for(int i = 0 ; i < even + odd -1; i++) {
c = c * 2 % mod;//将2的几次方转换成2与2乘
}
System.out.println(c);
}
n--;
}
}
}
我的一个错误:
算奇数的个数和偶数的个数时,要在while循环里面进行,因为对每组数据要重新算。
题目四:矩形总面积
【题目描述】
平面上有个两个矩形 R1 和 R2,它们各边都与坐标轴平行。设 (x1, y1) 和(x2, y2) 依次是 R1
的左下角和右上角坐标,(x3, y3) 和 (x4, y4) 依次是 R2 的左下角和右上角坐标,请你计算 R1 和 R2 的总面积是多少?注意:如果 R1 和 R2 有重叠区域,重叠区域的面积只计算一次。 输入格式 输入只有一行,包含 8个整数,依次是:x1,y1,x2,y2,x3,y3,x4 和 y4【输出格式】
一个整数,代表答案。
【样例输入】
2 1 7 4 5 3 8 6
【样例输出】
22
【提示】
样例中的两个矩形如图所示:
对于 20% 的数据,R1 和 R2 没有重叠区域。
对于 20% 的数据,其中一个矩形完全在另一个矩形内部。
对于 50% 的数据,所有坐标的取值范围是 [0, 10^3 ]。
对于 100% 的数据,所有坐标的取值范围是 [0, 10^5 ]。
package lan2023;
import java.util.Scanner;
public class D矩形总面积 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long x1 = sc.nextInt();
long y1 = sc.nextInt();
long x2 = sc.nextInt();
long y2 = sc.nextInt();
long x3 = sc.nextInt();
long y3 = sc.nextInt();
long x4 = sc.nextInt();
long y4 = sc.nextInt();
long s1 = (y2-y1)*(x2-x1);
long s2 = (y4-y3)*(x4-x3);
long sum = s1+s2;
long m1 = Math.max(Math.min(x1, x2), Math.min(x3,x4));
long n1 = Math.max(Math.min(y1, y2), Math.min(y3, y4));
long m2 = Math.min(Math.max(x1,x2),Math.max(x3,x4));
long n2 = Math.min(Math.max(y1,y2), Math.max(y3, y4));
if(m1<m2 && n1<n2) sum = sum - (m2-m1)*(n2-n1);
System.out.println(sum);
}
}
对于我自己用的是 if-else 只能通过几个测试点,这里我就给出正确的答案吧
注意的几点:
1.输入的数据要是long型的,因为题目中说对于 100% 的数据,所有坐标的取值范围是 [0, 10^5 ](10^5 * 10^5 = 10^10),我们算它的面积时,超出了整数所表示的范围(-2,147,483,648 到 2,147,483,647),所以要用long型,解题时要看数据的范围,看是否需要long型,
2.还有就是找重叠区域的方法,找重叠区域的左下角(m1,n1),和右上角(m2,n2) long m1 = max(min(x1,x2),min(x3,x4)) long n1 = max(min(y1,y2),min(y3,y4)) long m2 = min(max(x1,x2),max(x3,x4)) long n2 = min(max(y1,y2),max(y3,y4))
2022年
题目一:星期计算
【问题描述】
已知今天是星期六,请问天后是星期几?注意用数字 1 到 7 表示星期一到星期日。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
20的22次方是一个非常大的数,所以我们要用大数类。用 20的22次方除7看余数是多少。
方法一:
可以用计算器算出20的22次方%7==1,所以20的22次方天后是星期日,所以填写整数7。
方法二:
代码:
package lan2022;
import java.math.BigInteger;
public class A星期计算 {
public static void main(String[] args) {
BigInteger big = new BigInteger("20");
BigInteger sum = new BigInteger("1");
for(int i = 1; i <= 22; i++) {
sum = sum.multiply(big);
}
System.out.println(sum.mod(BigInteger.valueOf(7)));
}
}
在写代码的过程中:遇到一些问题:
1.定义sum的时候,我把sum初始化为0,那么乘的值则一直会是0
2.对7取模的时候,要将7转换成大数类
运行结果:1
答案:7
题目二:山
【问题描述】
这天小明正在学数数。他突然发现有些正整数的形状像一座“山”,比如 123565321,145541,它们左右对称(回文)且数位上的数字先单调不减,后单调不增。小明数了很久也没有数完,他想让你告诉他在区间 [2022, 2022222022] 中有多少个数的形状像一座“山”。【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
要在区间 [2022, 2022 22 2022]上找回文数,循环遍历找符合条件的回文数,并计数。
代码:
package lan2022;
public class B山 {
public static void main(String[] args) {
int count = 0;
for(int i = 2022; i <= 2022222022; i++) {
if(f(i)) {
count++;
}
}
System.out.println(count);
}
public static boolean f(int i) {
//对于回文数的判断,先判断0 和 个位为0,然后翻转数字判断是否是回文数
if(i < 0 || i % 10 == 0 && i != 0) {
return false;
}
//定义一个新数newnum 121
//newnum i ge newnum % 10
//0 121 1
//1 12 2
//12 1 ,退出循环
int newnum = 0;
while(i > newnum) {
int ge = i % 10;
if(ge < newnum%10) {
break;
}
newnum = newnum * 10 + ge;
i /= 10;
}
return i == newnum || i == newnum / 10;
}
}
运行结果:3181
其中有需要注意的易错点:
1.对于回文数的判断,先有一个提前判断的点:如果是数小于0或非零数的个位为0,则一定不是回文数
2.对于回文数中循环继续的条件 i>newnum ,这个用的是数字的翻转,i 和newnum是在不断地更新,直到i<=newnum退出循环,可以查看我之前的文章2.蓝桥杯小白 回文数 简单-CSDN博客
求回文数的代码:
public static boolean f(int i) {
//对于回文数的判断,先判断0 和 个位为0,然后翻转数字判断是否是回文数
if(i < 0 || i % 10 == 0 && i != 0) {
return false;
}
int newnum = 0;
while(i > newnum) {
int ge = i % 10;
newnum = newnum * 10 + ge;
i /= 10;
}
return i == newnum || i == newnum / 10;
}
题目三:字符统计
【问题描述】
给定一个只包含大写字母的字符串 S ,请你输出其中出现次数最多的字母。如果有多个字 母均出现了最多次,按字母表顺序依次输出所有这些字母。【输入格式】
一个只包含大写字母的字符串 S .【输出格式】
若干个大写字母,代表答案。【样例输入】
BABBACAC【样例输出】
AB【评测用例规模与约定】
对于 100% 的评测用例,1 ≤ |S | ≤ 10^6
因为要输出出现次数最多的字母,对于次数出现一样多的字母,则要按字母表顺序依次输出所有这些字母,所以我们要有一个计数的,针对不同的字母有不同的次数,我们此时定义一个26长的数组,用来存各个字母出现的次数,我们遍历字符串,将出现的字母加在对应的位置,我们可以用当前字母-’A‘ 来获取对应的数组下标。
然后就是在数组里面找出现次数最多的字母;我们可以把第一个字母设为出现次数最多的,结果就是A,然后遍历向后找如果找到比A出现次数多的,则更新,将结果也变为相应的字母,可以通过数字+’A‘算出ASCII码,在转换成字符类型得到字母。
代码:
package lan2022;
import java.util.Scanner;
public class C字符统计 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
char[] arr = s.toCharArray();
int[] count = new int[26];
for(int i =0; i <arr.length; i++) {
count[arr[i] - 'A'] +=1;
}
int max = count[0];
String result = "A";
for(int i = 1; i < count.length; i++) {
if(count[i] > max) {
max = count[i];
result = ""+(char)(i+'A');
}else if(count[i] == max) {
result += (char) (i+'A');
}
}
System.out.println(result);
}
}
出现的问题:
1.数字+’A‘是对应数字的ASCII码,我们把它强转成char就得到字符,一定是加(char)(i+'A')
2.本题中的result是一个字符串,所以要把转换好的字符 通过加空字符串,使之成为一个字符串
3.初始化max的时候,我误把他赋值成arr[0],这是代表字符数组,而我们应该赋值的是count[0]
4.字符串转化成字符数组:s.toCharArray();
题目四: 求阶乘数
满足N!的末尾恰好有K个 0 的最小的N是多少?
如果这样的N不存在输出-1 。【输入格式】
一个整数K。
【输出格式】
一个整数代表答案。
【样例输入】
2
【样例输出】
10
【评测用例规模与约定】
对于 30 %的数据, 1 ≤K ≤ 10 {^6}
对于 100 %的数据, 1 ≤ K ≤10 ^{18}
用于算阶乘后的0的个数:
public int trailingZeroes(int n) {
int sum = 0;
while(n != 0){
n /= 5;
sum += n;
}
return sum ;
}
int的最大值:2,147,483,647 2^31-1
long的最大值:9223372036854775807 2^63-1
代码:
package lan2022;
import java.util.Scanner;
public class E求阶乘数 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long k = sc.nextInt();
long start = 5;
long end = 2^63 - 1;
//二分法
while(start <= end) {
long mid = start + (end-start)/2;
long midcount = count(mid);
if(midcount < k) {
start = mid +1;
}else if(midcount > k){
end = mid - 1;
}else {
while(mid % 5 != 0) {
mid--;
}
System.out.println(mid);
return;
}
}
System.out.println(-1);
}
//编写一个方法用来计算阶乘数的末尾的0的个数
public static long count(long mid) {
long sum = 0;
while(mid > 0) {
mid/=5;
sum += mid;
}
return sum;
}
}
2021年
题目一:ASC
已知大写字母 A 的 ASCII 码为 65,请问大写字母 L 的 ASCII 码是多少?
两个方法:
1.看L与A之间差多少,然后再加上65
2.将字符’L‘直接转换成int类型(强制类型转换)
package lan2021;
public class AASC {
public static void main(String[] args) {
System.out.println('L'-'A'+65);
System.out.println((int)'L');
}
}
题目二:卡片
小蓝有很多数字卡片,每张卡片上都是数字 0 到 9。 小蓝准备用这些卡片来拼一些数,他想从 1 开始拼出正整数,每拼一个, 就保存起来,卡片就不能用来拼其它数了。 小蓝想知道自己能从 1 拼到多少。 例如,当小蓝有 30张卡片,其中 0 到 9 各 3 张,则小蓝可以拼出 1 到 10, 但是拼 11 时卡片 1 已经只有一张了,不够拼出 11。 现在小蓝手里有 0到 9的卡片各 2021 张,共 20210 张,请问小蓝可以从 1拼到多少? 提示:建议使用计算机编程解决问题。
我们可以把0到9的卡片的个数存放在一个数组里面,然后当我们用了一张之后,将对应的数量减一, 然后循环从1开始拼,看能拼到哪个数字,然后对每个数字进行处理,先得到个位数,看这个数在数组里面是否还有,如果有的话,我们将其个数-1,如果没有的话,我们退出内层循环,同时退出外层循环,因为已经出现拼不出的数字了。
代码:
package lan2021;
public class B卡片 {
public static void main(String[] args) {
int[] arr = new int[10];
for(int i = 0; i < arr.length; i++) {
arr[i] = 2021;
}
int i;
boolean flag = true;
for(i = 1; ;i++) {
int temp = i;
while(temp > 0) {
int ge = temp % 10;//得到的个位数正好是对应数组的下标
if(arr[ge] != 0) {
arr[ge]--;
}else {
flag = false;
break;
}
temp /= 10;
}
if(flag == false) break;
}
System.out.println(i-1);
}
}
运行结果: 3181
题目三:货物摆放
现在,小蓝有 n箱货物要摆放在仓库,每箱货物都是规则的正方体。小蓝规定了长、宽、高三个互相垂直的方向,每箱货物的边都必须严格平行于长、宽、高。小蓝希望所有的货物最终摆成一个大的长方体。即在长、宽、高的方向上分别堆 L、W、H 的货物,满足n=L×W×H。
给定 n,请问有多少种堆放货物的方案满足要求。例如,当 n = 4 时,有以下 6 种方案:1×1×4、1×2×2、1×4×1、2×1×2、2 × 2 × 1、4 × 1 × 1。请问,当 n = 2021041820210418(注意有 16位数字)时,总共有多少种方案?提示:建议使用计算机编程解决问题。
由题意知,L,W,H都是n的因数,对于数n,我们要先找到这些因数,如果因数的成绩等于n的话,我们就将计数器加1。
代码:
package lan2021;
import java.util.*;
public class F时间显示 {
public static void main(String[] args) {
long n = 2021041820210418L;
List<Long> L= new ArrayList<>();
for(Long i = (long) 1; i * i <= n; i++) {
if(n % i == 0) {
L.add(i);
if(i != n/i) {
L.add(n/i);
}
}
}
int count = 0;
for(int i = 0; i < L.size(); i++) {
for(int j = 0; j < L.size(); j++) {
if(L.get(i) * L.get(j) > n) {
continue;
}
for(int k = 0; k < L.size(); k++) {
if(L.get(i) * L.get(j) * L.get(k) == n) {
count ++;
}
}
}
}
System.out.println(count);
}
}
运行结果:2430
自己的问题:
1.再往列表里加n的因数的时候,i要定义为long型,但不是Long 包装类,然后添加数的时候,
2.然后定义列表List<Long> L = new ArrayList<>();
3.往列表里添加元素
for(long i = 1; i * i <= n; i++) {
if(n % i == 0) {
L.add(i);
if(i != n/i) {
L.add(n/i);
}
}4.List的方法:
L.size()求L的长度
L.get()得到元素
L.add()添加元素
题目四:时间显示
【题目描述】
小蓝要和朋友合作开发一个时间显示的网站。在服务器上,朋友已经获取了当前的时间,用一个整数表示,值为从 19701970 年 11 月 11 日 00:00:0000:00:00 到当前时刻经过的毫秒数。现在,小蓝要在客户端显示出这个时间。小蓝不用显示出年月日,只需要显示出时分秒即可,毫秒也不用显示,直接舍去即可。给定一个用整数表示的时间,请将这个时间对应的时分秒输出。【输入描述】
输入一行包含一个整数,表示时间。【输出描述】
输出时分秒表示的当前时间,格式形如 HH:MM:SS,其中 HH 表示时,值为 00 到 2323,MM 表示分,值为 00 到 5959,SS 表示秒,值为 00 到 5959。时、分、秒 不足两位时补前导 00。【输入输出样例】
示例 1
输入46800999
输出13:00:00
示例 2
输入1618708103123
输出01:08:23
评测用例规模与约定
对于所有评测用例,给定的时间为不超过 10的18次方的正整数。运行限制
最大运行时间:1s
最大运行内存: 512M
代码:
package lan2021;
import java.util.Scanner;
public class G时间显示 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long n = sc.nextLong();
n = n / 1000;
System.out.printf("%02d:%02d:%02d",(n % (3600 * 24))/3600,(n%3600)/60,n% 60);
}
}
注意:
1.因为输入的n是一个毫秒级别的,而题目要的是秒,所以我们要进行转换n/1000
2.输出的是printf,输出格式化的结果
3.将n对60s取余,表示还剩多少秒 ,n对60*60取余,表示还剩多少分钟,n对60*60*24,表示还剩多少多少小时
题目五:杨辉三角
下面的图形是著名的杨辉三角形:
如果我们按从上到下、从左到右的顺序把所有数排成一列,可以得到如下数列: 1, 1, 1, 1, 2, 1, 1, 3, 3, 1, 1, 4, 6, 4, 1, ⋯
给定一个正整数 N,请你输出数列中第一次出现 N是在第几个数?
输入描述
输入一个整数 N。输出描述
输出一个整数代表答案。输入输出样例
示例 1
输入6
输出13
评测用例规模与约定
对于 20% 的评测用例,1≤N≤10; 对于所有评测用例,1≤N≤1000000000。运行限制
最大运行时间:1s
最大运行内存: 256M
注意注意注意!下面不是最正确的答案,效率也不高
package lan2021;
import java.util.Scanner;
public class H杨辉三角 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int n = 20;
int[][] a = new int[n][n];
for(int i = 0; i < a.length; i++) {
for(int j = 0; j <= i; j++) {
if(j == 0 || j == i) {
a[i][j] = 1;
}else {
a[i][j] = a[i-1][j-1]+a[i-1][j];
}
System.out.print(a[i][j] +"\t");
}
System.out.println();
}
int count = 0;
boolean flag = true;
for(int i = 0; i < a.length; i++) {
for(int j = 0; j <= i; j++) {
count++;
if(a[i][j] == N) {
flag = false;
break;
}
}
if(flag == false) break;
}
System.out.println(count);
}
}
输出杨辉三角:
package 杨辉三角;
public class test1 {
public static void main(String[] args) {
//下三角矩阵
int[][] arr = new int [10][10];
for(int i = 0; i < arr.length; i++) { //外层循环控制的是整个二维数组的行
for(int j = 0; j <= i; j++) { //内层循环控制的是每行的列
//对数字的输出做一些改变
//每一行的最左边和最右边总是1
//第i行的j值 是第i-1行的 j-1的值 加 第i-1行的j值
if(j == 0 || j == i) {
arr[i][j] = 1;
}else {
arr[i][j] = arr[i-1][j-1]+ arr[i-1][j];
}
System.out.print(arr[i][j] + "\t");
}
System.out.println();
}
}
}
杨辉三角需要注意的几点:
1.外层循环控制的是行数
2.进行赋值的时候,if的条件判断是||
等边三角形:
package 杨辉三角;
public class B等边三角形 {
public static void main(String[] args) {
int rows = 10;
for(int i = 0; i < rows; i++) {
int num = 1;
System.out.format("%" + (rows - i)*2 + "s", "");//s代表的是字符串类型
for(int j = 0; j < i; j ++) {
System.out.format("%4d" , num);
num = num * (i-j)/(j+1);
}
System.out.println();
}
}
}
题目六:最少砝码
问题描述
你有一架天平。现在你要设计一套砝码,使得利用这些砝码可以称出任意 小于等于 N的正整数重量。那么这套砝码最少需要包含多少个砝码?注意砝码可以放在天平两边。输入格式
输入包含一个正整数 N。输出格式
输出一个整数代表答案。样例输入
7
样例输出
3
样例说明
3 个砝码重量是 1、4、6,可以称出 1 至 7的所有重量。1 = 1;
2 = 6 − 4(天平一边放 66,另一边放 44);
3 = 4 − 1;
4 = 4;
5 = 6 − 1;
6 = 6;
7 = 1 + 6;
少于 3 个砝码不可能称出 1 至 7 的所有重量。
评测用例规模与约定
对于所有评测用例,1 ≤ N ≤ 1000000000。运行限制
最大运行时间:1s
最大运行内存: 512M
package lan2021;
import java.util.Scanner;
public class G最少砝码 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int now = 1, sum = 1, count = 1;
while(sum<n) {
count++;
now *= 3;
sum+=now;
}
System.out.println(count);
}
}
注意:
1.循环的执行条件是sum<n
2.输出的是count
3.三个变量的初值都为一
2020年
题目一:解密
【问题描述】
小明设计了一种文章加密的方法:对于每个字母 c,将它变成某个另外的字符 Tc。下表给出了字符变换的规则:
例如,将字符串 YeRi 加密可得字符串 EaFn。
小明有一个随机的字符串,加密后为EaFnjISplhFviDhwFbEjRjfIBBkRyY(由 30 个大小写英文字母组成,不包含换行符),请问原字符串是多少?(如果你把以上字符串和表格复制到文本文件中,请务必检查复制的内容是否与文档中的一致。在试题目录下有一个文件 str.txt,第一行为上面的字符串,后面 52 行依次为表格中的内容。)
【答案提交】
这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个只包含 30 个大小写英文字母的字符串,在提交答案时只填写这个字符串,填写多余的内容将无法得分。
1.可以直接对应着写
2.代码:
package lan2020;
public class A解密 {
public static void main(String[] args) {
String s = "EaFnjISplhFviDhwFbEjRjfIBBkRyY";
char[] arr = s.toCharArray();
String s1 = "abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ";
String s2 = "yxmdacikntjhqlgoufszpwbrevYXMDACIKNTJHQLGOUFSZPWBREV";
String s3 = "";
for(int i = 0; i < arr.length;i ++) {
int j = s2.indexOf(arr[i]);
s3 += s1.substring(j, j+1);
}
System.out.println(s3);
}
}
注意:
1.s2.indexOf(a):返回a字母在字符串s2的下标
2.s3+=,而不是=,要把每次获得的一个字符加到s3里面
3.s1.substring(a,b):获取s1的a到b位置的字符
题目二:纪念日
【问题描述】
2020 年 7 月 1 日是中国共产党成立 99 周年纪念日。中国共产党成立于 1921 年 7 月 23 日。问从 1921 年 7 月 23 日中午 12 时到 2020 年 7 月 1 日中午 12 时一共包含多少分钟?
【答案提交】
这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个 整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
1.用计算器算出这两天间隔36138天,一天24小时,1小时60分钟,36138*24*60
二.代码:
package lan2020;
import java.text.ParseException;//处理字符串转日期时候的异常
import java.text.SimpleDateFormat;//格式化和解析日期的类
import java.util.Date;//date类代表特定的时间点
public class B纪念日 {
public static void main(String[] args) throws ParseException {
SimpleDateFormat time = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss");
Date start = time.parse("1921-7-23 00:00:00");
Date end = time.parse("2020-7-1 00:00:00");
long cha = end.getTime()-start.getTime();//getTime()返回的是long类型的毫秒数
System.out.println(cha /(60*1000));//将毫秒转为分钟
}
}
注意几个关键字:
parseException
SimpleDateFormat time = new SimpleDateFormat("ssss-zz-cc jj:kk:ww");
time.parse
getTime
题目三:合并检测
【问题描述】
新冠疫情由新冠病毒引起,最近在 A 国蔓延,为了尽快控制疫情,A 国准备给大量民众进病毒核酸检测。
然而,用于检测的试剂盒紧缺。为了解决这一困难,科学家想了一个办法:合并检测。即将从多个人(k 个)采集的标本放到同一个试剂盒中进行检测。如果结果为阴性,则说明这 k 个人都是阴性,用一个试剂盒完成了 k 个人的检测。如果结果为阳性,则说明至少有一个人为阳性,需要将这 k 个人的样本全部重新独立检测(从理论上看,如果检测前 k − 1 个人都是阴性可以推断出第 k 个人是阳性,但是在实际操作中不会利用此推断,而是将 k 个人独立检测),加上最开始的合并检测,一共使用了 k + 1 个试剂盒完成了 k 个人的检测。
A 国估计被测的民众的感染率大概是 1%,呈均匀分布。请问 k 取多少能最节省试剂盒?
因为我看不懂代码,所以我要用数学方法
答案:10
题目四:分类计数
【问题描述】
输入一个字符串,请输出这个字符串包含多少个大写字母,多少个小写字
母,多少个数字。【输入格式】
输入一行包含一个字符串。
【输出格式】
输出三行,每行一个整数,分别表示大写字母、小写字母和数字的个数。
测试样例
Input:
1+a=AabOutput:
1
3
1
评测用例规模与约定对于所有评测用例,字符串由可见字符组成,长度不超过 100。
package lan2020;
import java.util.Scanner;
public class F分类计数 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
char[] arr = s.toCharArray() ;
int a=0,b=0,c=0;
for(int i = 0; i < arr.length; i++) {
if(arr[i] >= 'A' && arr[i] <= 'Z') {
a++;
}
if(arr[i] >= 'a' && arr[i] <= 'z') {
b++;
}
if(arr[i] >= '0' && arr[i] <='9') {
c++;
}
}
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
}
题目五:八次求和
【问题描述
给定正整数 n ,求1^8 + 2^8+ · · · + n^8 mod 123456789的值。其中 mod 表示取余。
【输入格式
输入的第一行包含一个整数 n。
【输出格式
输出一行,包含一个整数,表示答案
【测试样例1
Input:
2Output:
257
【测试样例2Input:
987654Output:
43636805
【评测用例规模与约定对于 20% 的评测用例,1 ≤ n ≤ 20。
对于 60% 的评测用例,1 ≤ n ≤ 1000。
对于所有评测用例,1 ≤ n ≤ 1000000。
这个是对部分的评测是有效的。
package lan2020;
import java.util.Scanner;
public class G八次求和 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);;
int n =sc.nextInt();
int mod = 123456789;
int sum =0;
for(int i = 1; i <= n; i++) {
sum+= i*i*i*i*i*i*i*i;
}
System.out.println(sum);
}
}
要相对所有的数据都有效,用到大数类(n<=1000000,n^8肯定超过了long 型的范围)
package lan2020;
import java.math.BigInteger;
import java.util.Scanner;
public class F八次求和2 {
static BigInteger mod= new BigInteger("123456789");
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//BigInteger n = sc.nextBigInteger();
int n = sc.nextInt();
BigInteger sum = new BigInteger("0");
for(int i = 1;i <= n;i++ ) {
//因为sum是大数类,所以加的时候要把i转换成大数类
BigInteger t = BigInteger.valueOf(i);
sum = sum.add(t.multiply(t).multiply(t).multiply(t).
multiply(t).multiply(t).multiply(t).
multiply(t));
}
System.out.println(sum.mod(mod));
}
}
问题:
1.我写的时候还想把i也当成大数类,但是i作为循环中判断i<n,可以先定义为int 型,之后用BigInteger.valueOf(i)转换成大数类
2.大数类的这些方法比如add(), subtract()都是 返回一个新的大数对象,所以在输出sum.mod()时的sum还是原来的sum的初值,所以要将乘的结果再次赋值给sum.
3.注意代码中8次相乘的写法
2019年
题目一:组队
作为篮球队教练,你需要从以下名单中选出 1 号位至 5 号位各一名球员, 组成球队的首发阵容。每位球员担任 1 号位至 5 号位时的评分如下表所示。
请你计算首发阵容 1 号位至 5 号位的评分之和最大可能是多少?(如果你把以上文字复制到文本文件中,请务必检查复制的内容是否与文 档中的一致。在试题目录下有一个文件 team.txt,内容与上面表格中的相同, 请注意第一列是编号)
97+99+99+97+98=490
题目二:不同子串
题目描述
一个字符串的非空子串是指字符串中长度至少为 1 的连续的一段字符组成 的串。例如,字符串aaab 有非空子串a, b, aa, ab, aaa, aab, aaab,一共 7 个。 注意在计算时,只算本质不同的串的个数。请问,字符串0100110001010001 有多少个不同的非空子串?
大致思路:对于字符串返回子串的长度,然后字串的范围遍历所有的位置。
代码:
package lan2019;
import java.util.HashSet;
import java.util.Set;
public class C数列求和 {
public static void main(String[] args) {
String s = "0100110001010001";
Set<String> set = new HashSet<String>();
for(int i = 0; i < s.length(); i++) {
for(int j = i; j < s.length(); j++) {
set.add(s.substring(i,j+1));
}
}
System.out.println(set.size());;
}
}
运行结果:100
题目三: 数列求值
题目描述
给定数列 1, 1, 1, 3, 5, 9, 17, …,从第 4 项开始,每项都是前 3 项的和,求 第 20190324 项的最后 4 位数字。
package lan2019;
public class C数列求和 {
public static void main(String[] args) {
int a = 1,b =1,c = 1;
for(int i = 3; i < 20190324; i++) {
int t = (a+b+c) % 10000;
a = b;
b = c;
c = t;
}
System.out.println(c);
}
}
运行结果:4659
注意:
1.a , b都是直接被覆盖的,在此之前,要先算出t的值,不然你先覆盖了则找不到最初的数了
2.关于i的范围,一定要拿题目中的例子试一下,不要盲目自大 i<第几项,不是<=
3.获得最后的几位数字是要取余,几位就有几个0
题目四: 数的分解
把 2019 分解成 3 个各不相同的正整数之和,并且要求每个正整数都不包 含数字 2 和 4,一共有多少种不同的分解方法?注意交换 3 个整数的顺序被视为同一种方法,例如 1000+1001+18 和 1001+1000+18 被视为同一种。
代码:
package lan2019;
public class E数的分解 {
public static void main(String[] args) {
int n = 2019;
int count = 0;
for(int i = 1; i < n; i++) {
if((i+ "").indexOf("2") != -1 || (i+ "").indexOf("4") != -1)
continue;
for(int j = i + 1; j < n; j++) {
if((j + "").indexOf("2") != -1 || (j + "").indexOf("4") != -1) {
continue;
}
int k = n - i - j;
if(k == i || i == j || k==j) {
continue;
}
if(k > 0 && (k + "").indexOf("2") == -1 && (k + "").indexOf("4") == -1) {
count++;
}
}
}
System.out.println(count / 3);
}
}
注意:
1.一种很新的遍历方式,第三个数是用总数减第一个和第二个数得来的,如果是我的话我可能会三层for循环遍历
2.外层循环的i是从1开始的,因为第一位不能为0
3.是< n,不是<=n,
4.j的开始条件是i+1,不是i的原因是题目中说这三个数不能相同
5.题目中说不能出现2和4,则将当前数字转换成字符串 判断索引 ,!= “2”不符合条件 或者 i!=“4”不符合条件,注意注意!!!是或的关系,不满足其中一个则不符合条件
题目五:特别的数
小明对数位中含有 2、0、1、9 的数字很感兴趣(不包括前导 0),在 1 到 40 中这样的数包括 1、2、9、10 至 32、39 和 40,共 28 个,他们的和是 574。请问,在 1 到 n 中,所有这样的数的和是多少?
【输入格式】
输入一行包含一个整数 n。【输出格式】
输出一行,包含一个整数,表示满足条件的数的和。
【样例输入】
40
【样例输出】
574
【评测用例规模与约定】
对于 20% 的评测用例,1≤n≤10。
对于 50% 的评测用例,1≤n≤100。
对于 80% 的评测用例,1≤n≤1000。
对于所有评测用例,1≤n≤10000。
时间限制:1.0s
内存限制:512.0MB
package lan2019;
import java.util.Scanner;
public class F特别的数 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int sum = 0;
for(int i = 1; i <= 40;i++) {
if((i + "").indexOf("2") != -1 ||(i+ "").indexOf("0") != -1
|| (i +"").indexOf("1") != -1 ||
(i +" ").indexOf("9") != -1) {
sum+=i;
}
}
System.out.println(sum);
}
}