相关题目:
2016年第七届蓝桥杯真题解析JavaB组
2016年第七届蓝桥杯真题解析JavaC组
2017年第八届蓝桥杯真题解析JavaB组
2017年第八届蓝桥杯真题解析JavaC组
2018年第九届蓝桥杯真题解析JavaB组
2018年第九届蓝桥杯真题解析JavaC组
2019年第十届蓝桥杯真题解析JavaB组
2019年第十届蓝桥杯真题解析JavaC组
2020年第十一届蓝桥杯JavaB组(七月场)真题解析
2020年第十一届蓝桥杯JavaC组(七月场)真题解析
2020年第十一届蓝桥杯JavaB组(十月场)真题解析
2020年第十一届蓝桥杯JavaC组(十月场)真题解析
题目:
小蓝要为一条街的住户制作门牌号。
这条街一共有 2020 位住户,门牌号从 1 到 2020 编号。
小蓝制作门牌的方法是先制作 0 到 9 这几个数字字符,最后根据需要将字
符粘贴到门牌上,例如门牌 1017 需要依次粘贴字符 1、0、1、7,即需要 1 个
字符 0,2 个字符 1,1 个字符 7。
请问要制作所有的 1 到 2020 号门牌,总共需要多少个字符 2?
解析:
这个用个循环,1——2020,再取余判断一下
代码:
public class 门牌制作 {
public static void main(String[] args) {
int count=0;
for(int i=1;i<=2020;i++){
int tempi=i;
while (tempi>0){
//取余数对每个数分别判断
int k=tempi%10;
if(k==2)
count++;
tempi/=10;
}
}
System.out.println(count);
}
}
答案:624
题目:
小蓝有一个数字矩阵,里面只包含数字 0 和 2。小蓝很喜欢 2020,他想找
到这个数字矩阵中有多少个 2020 。
小蓝只关注三种构成 2020 的方式:
1.同一行里面连续四个字符从左到右构成 2020。
2.同一列里面连续四个字符从上到下构成 2020。
3.在一条从左上到右下的斜线上连续四个字符,从左上到右下构成 2020。
例如,对于下面的矩阵:
220000
000000
002202
000000
000022
002020
一共有 5 个 2020。其中 1 个是在同一行里的,1 个是在同一列里的,3 个
是斜线上的。
小蓝的矩阵比上面的矩阵要大,由于太大了,他只好将这个矩阵放在了一
个文件里面,在试题目录下有一个文件 2020.txt,里面给出了小蓝的矩阵。
请帮助小蓝确定在他的矩阵中有多少个 2020。
(测试数据太大了我就不放这里了,我放个图片大概是这样子的)
思路:
1.暴力搜之前,要知道它每行每列的长度,一个简单的方法
从最左上角把鼠标按往一直往最右下角拉,记事本右下角
就会自己显示,我考试的时候没想起来这样做,吐血。
2.然后就是搜索,从左往右从上往下,只要找到一个"2",就
可以开始深搜,分别找每个'2'的四个方向上下左右,左上到右下,
每当有一个方向上是符合条件的就count++;
代码:
import java.util.Scanner;
public class 寻找2020 {
static int count=0;
static char [][]arr2=new char[400][400];
static char []arr3={'2','0','2','0'};
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
String []arr=new String[301];
for(int i=0;i<300;i++){
arr[i]=input.next();
}
for(int i=0;i<300;i++){
arr2[i]=arr[i].toCharArray();
}
for(int i=0;i<300;i++){
for(int j=0;j<300;j++){
if(arr2[i][j]=='2'){
dfs(i,j);
}
}
}
System.out.println(count);
}
public static void dfs(int x,int y){
int flag=1;//用来判断是否满足条件
//找从左往右
for(int i=1;i<=3;i++){
//越界了就说明这个方向肯定不行
if(y+i<0||y+i>=300)
{
flag=0;
break;
}
if(arr2[x][y+i]!=arr3[i]){
flag=0;
break;
}
}
if(flag==1)
count++;
//每判断一次要更新flag=1,以免对下一次判断造成误解
flag=1;
//从上到下
for(int i=1;i<=3;i++){
if(x+i<0||x+i>=300)
{
flag=0;
break;
}
if(arr2[x+i][y]!=arr3[i]) {
flag=0;
break;
}
}
if(flag==1 )
count++;
flag=1;
//左上到右下
for(int i=1;i<=3;i++){
if((y+i<0||y+i>=300)||(x+i<0&&x+i>=300)){
flag=0;
break;
}
if(arr2[i+x][y+i]!=arr3[i]){
flag=0;
break;
}
}
if(flag==1)
count++;
}
}
答案:
16520
题目:
如下图所示,小明用从 1 开始的正整数“蛇形”填充无限大的矩阵。
1 2 6 7 15 ...
3 5 8 14 ...
4 9 13 ...
10 12 ...
11 ...
...
容易看出矩阵第二行第二列中的数是 5。请你计算矩阵中第 20 行第 20 列
的数是多少?
思路:
我们把这个数组多写几项
1 2 6 7 15 16 28 29 45
3 5 8 14 17 27 30 44
4 9 13 18 26 31 43
10 12 19 25 32 42
11 20 24 33 41
21 23 34 40
22 35 39
36 38
37
把n行n列的数提取出来
1 5 13 25 41
可以看出一个规律
1+4=5
1+4+8=13
1+4+8+12=25
1+4+8+12+16=41
所以答案1加上就是首项为4,公差为4的前19项的等差数列和
ans=(4+4*19)*19/2=761
答案:
761
代码我没想到:在网上找到一个大哥写的,链接在这大佬
public class Test {
public static void main(String[] args) {
int[][] map = new int[201][201];
int n = 0;
for (int k = 1; k <= 200; k++)
for (int i = 1; i <= k; i++)
map[i][k - i + 1] = ++n;
System.out.print(map[20][20]);
}
}
题目:
上图给出了七段码数码管的一个图示,数码管中一共有 7 段可以发光的二
极管,分别标记为 a, b, c, d, e, f, g。
小蓝要选择一部分二极管(至少要有一个)发光来表达字符。在设计字符
的表达时,要求所有发光的二极管是连成一片的。
例如:b 发光,其他二极管不发光可以用来表达一种字符。
例如:c 发光,其他二极管不发光可以用来表达一种字符。
这种方案与上一行的方案可以用来表示不同的字符,尽管看上去比较相似。
例如:a, b, c, d, e 发光,f, g 不发光可以用来表达一种字符。
例如:b, f 发光,其他二极管不发光则不能用来表达一种字符,因为发光
的二极管没有连成一片。
请问,小蓝可以用七段码数码管表达多少种不同的字符?
思路:
大体思路是这样
1.要求多少种不同的表达式,换一种说法a~g所有的灯排成一行,放进一个
一维数组(递归实现指数型枚举),每次从中选取人n个灯,选到的灯变亮,
不选的不亮,这样就把所有情况都包含进来,我们只需判断每一种情况是否
合法,和发则ans++;
2.为了更好的判断所有亮的灯是否联通,把原图转换成一下这种二维图
然后六个方向搜索就行了,哪六个呢:右下、左下、左上、右上、下两格、上两格;
3.注意并不是所有的灯都有以上这六种方向,看原图的灯,如果a和g这
两个灯亮了并不满足题意,因为它们不相连,因此a、g、d这个一列所搜的
时候不会有六个方向只会有四个;
import java.util.Scanner;
public class 七段码 {
static int N=7;
static int ans=0;
static int countdeng=0;//每一次深搜时亮灯的个数
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
//把所有灯的情况全部判断出来,然后判断此时的情况是否合法
//第一步深搜枚举
int []arr=new int[8];
int []vis=new int[8];
dfs(arr,vis,1);
System.out.println(ans);
}
static void dfs(int []arr,int []vis,int level){
if(level>7){
check(arr);
return;
}
//一共就两种情况,一种是要当前这个灯亮,一种是不要,分别深搜就行
vis[level]=1;
arr[level]=1;
dfs(vis,arr,level+1);
vis[level]=0;
arr[level]=0;
dfs(vis,arr,level+1);
}
static void check(int []arr){
//先把此时灯亮的情况,在表格中显示出来,如果某一个灯需要亮
//在二维表格中它对应的数就为1;
int [][]map=new int[6][4];
int [][]tempmap=new int[6][4];
//a
map[1][2]=arr[1];
//b
map[2][3]=arr[2];
//c
map[4][3]=arr[3];
//d
map[5][2]=arr[4];
//e
map[4][1]=arr[5];
//f
map[2][1]=arr[6];
//g
map[3][2]=arr[7];
//我们要看此时灯是否能连起来
//可以还用深搜,先把所有的灯亮的个数记录起来
//然后以其中一个亮点为起点,向其中六个方向深搜
//每找到一个一个可以联通的点总的灯数就减去一
//最后全部搜完后还剩一盏灯亮着就说明当前方案可行,反之则不行
//找总共有多少盏灯亮着
//所欲多次深搜要初始化
countdeng=0;
for(int i=1;i<=5;i++) {
for (int j = 1; j <= 3; j++) {
if (map[i][j] != 0)
countdeng++;
}
}
//找到了所有灯之后,找一个亮灯的点,开始深搜
int flag=0;//只需要找一个点深搜即可,搜一次后就全部停止
for(int i=1;i<=5;i++){
for(int j=1;j<=3;j++) {
if (map[i][j] != 0) {
flag = 1;
check2(map,tempmap, i, j);
break;
}
}
if (flag==1)
break;
}
if(countdeng-1==0)
{
ans++;
}
}
//能走的六个方向
public static int []xx={1,1,-1,-1,-2,2};//2和-2是因为原图中两个边上的相连也算
//转换成二维图就是加-2和加2
public static int []yy={-1,1,-1,1,0,0};
static void check2(int [][]map,int [][]temp,int x,int y){
temp[x][y]=1;//起始点也要标记下
for(int i=0;i<6;i++){
if(y==2&&i>=4){
continue;
}
//这一步很重要,因为中间的a,g,d按原图来是不能上下跳的,这样按原图来是不连续的
//然后就是判断是否越界,是否已经找过,是否灯亮
int tempx=x+xx[i];
int tempy=y+yy[i];
//看是否越界
if(tempx>5||tempx<1)
continue;
if(tempy>3||tempy<1)
continue;
//是否找到过
if(temp[tempx][tempy]!=0)
continue;
//判断这个点是否有
if(map[tempx][tempy]==0)
continue;
if (map[tempx][tempy]==1) {
temp[tempx][tempy] = 1;
countdeng--;
check2(map, temp, tempx, tempy);
}
}
return ;
}
}
问题:
小蓝最近学习了一些排序算法,其中冒泡排序让他印象深刻。在冒泡排序中,每次只能交换相邻的两个元素。
小蓝发现,如果对一个字符串中的字符排序,只允许交换相邻的两个字符,则在所有可能的排序方案中,冒泡排序的总交换次数是最少的。
例如,对于字符串 lan 排序,只需要 1 次交换。对于字符串 qiao 排序,总共需要 4 次交换。
小蓝找到了很多字符串试图排序,他恰巧碰到一个字符串,需要 100 次交换,可是他忘了吧这个字符串记下来,现在找不到了。
请帮助小蓝找一个只包含小写英文字母且没有字母重复出现的字符串,对该串的字符排序,正好需要 100 次交换。如果可能找到多个,请告诉小蓝最短的那个。如果最短的仍然有多个,请告诉小蓝字典序最小的那个。请注意字符串中不可以包含相同的字符。
太菜了写不来看不懂
问题:
小蓝给学生们组织了一场考试,卷面总分为 100 分,每个学生的得分都是
一个 0 到 100 的整数。
请计算这次考试的最高分、最低分和平均分。
输入格式
输入的第一行包含一个整数 n,表示考试人数。
接下来 n 行,每行包含一个 0 至 100 的整数,表示一个学生的得分。
输出格式
输出三行。
第一行包含一个整数,表示最高分。
第二行包含一个整数,表示最低分。
第三行包含一个实数,四舍五入保留正好两位小数,表示平均分。
测试样例:
输入:
7
80
92
56
74
88
99
10
输出:
99
10
71.29
这个很基本直接上代码
import java.util.Arrays;
import java.util.Scanner;
public class 成绩分析 {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
int n=input.nextInt();
int []arr=new int[n];
double sum=0;
for(int i=0;i<n;i++){
arr[i]=input.nextInt();
sum+=arr[i];
}
Arrays.sort(arr);
System.out.println(arr[n-1]);
System.out.println(arr[0]);
System.out.println(String.format("%.2f",sum/n));
}
}
问题:
小蓝正在学习一门神奇的语言,这门语言中的单词都是由小写英文字母组成,有些单词很长,远远超过正常英文单词的长度。小蓝学了很长时间也记不住一些单词,他准备不再完全记忆这些单词,而是根据单词中哪个字母出现得最多来分辨单词。
现在,请你帮助小蓝,给了一个单词后,帮助他找到出现最多的字母和这个字母出现的次数。
输入格式
输入一行包含一个单词,单词只由小写英文字母组成。
输出格式
输出两行,第一行包含一个英文字母,表示单词中出现得最多的字母是哪
个。如果有多个字母出现的次数相等,输出字典序最小的那个。
第二行包含一个整数,表示出现得最多的那个字母在单词中出现的次数
测试样例1
输入:
lanqiao
输出:
a
2
测试样例2
输入:
longlonglongistoolong
输出:
o
6
注意: 这个输出字典序最小的
import java.util.Scanner;
public class 单词分析 {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
String a=input.next();
char []arr=a.toCharArray();
int max=-1;
int maxchar=' ';
int []count=new int[129];
for(int i=0;i<arr.length;i++){
count[arr[i]]++;
}
for(int i=0;i<=128;i++){
if(count[i]>max){
max=count[i];
maxchar=i;
}
}
System.out.println((char)(maxchar));
System.out.println(max);
}
}
上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。
对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和。
路径上的每一步只能从一个数走到下一层和它最近的左边的那个数或者右边的那个数。此外,向左下走的次数与向右下走的次数相差不能超过 1。
输入格式
输入的第一行包含一个整数 N (1 < N ≤ 100),表示三角形的行数。下面的
N 行给出数字三角形。数字三角形上的数都是 0 至 100 之间的整数
输出格式
输出一个整数,表示答案。
思路:
这题要想的一点就是`“左下走的次数与向右下走的次数相差不能超过 1”
看着两个草图就比较好理解了,只要理解的剩下的就是dp
import java.util.Scanner;
public class 数字三角形 {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
int n=input.nextInt();
int [][]arr=new int[n+1][n+1];
int [][]dp=new int[n+1][n+1];
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
arr[i][j]=input.nextInt();
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
//最里面一列只能从上面下来
if(j==1){
dp[i][j]=dp[i-1][j]+arr[i][j];
}
//每行最边上一列只能从左上角下来
else if(i==j){
dp[i][j]=dp[i-1][j-1]+arr[i][j];
}
else {
dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-1])+arr[i][j];
}
}
}
if(n%2!=0){
System.out.println(dp[n][n/2+1]);
}
else {
System.out.println(Math.max(dp[n][n/2+1],dp[n][n/2]));
}
}
}
题目:
对于一个字符串 S,我们定义 S 的分值 f(S ) 为 S 中出现的不同的字符个
数。例如 f(”aba”) = 2,f(”abc”) = 3, f(”aaa”) = 1。
现在给定一个字符串 S [0…n − 1](长度为 n),请你计算对于所有 S 的非空
子串 S [i… j](0 ≤ i ≤ j < n),f(S [i… j]) 的和是多少。
输入格式
输入一行包含一个由小写字母组成的字符串 S。
输出格式
输出一个整数表示答案。
测试样例1
样例输入:
ababc
样例输出:
28
样例说明:
子串 f值
a 1
ab 2
aba 2
abab 2
ababc 3
b 1
ba 2
bab 2
babc 3
a 1
ab 2
abc 3
b 1
bc 2
c 1
评测用例规模与约定
对于 20% 的评测用例,1 ≤ n ≤ 10;
对于 40% 的评测用例,1 ≤ n ≤ 100;
对于 50% 的评测用例,1 ≤ n ≤ 1000;
对于 60% 的评测用例,1 ≤ n ≤ 10000;
对于所有评测用例,1 ≤ n ≤ 100000。
思路:
这题我是暴力写的应该只能50%的分,但是我在网上看到一大哥用
HashSet去重,应该能拿60%的分
大佬题解
import java.util.HashSet;
import java.util.Scanner;
public class 子串分值和 {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
int count=0;
String word=input.next();
char []arr=word.toCharArray();
int length=word.length();
for(int i=0;i<length;i++){
HashSet<Character> map=new HashSet<>();
for(int j=i;j<length;j++){
map.add(arr[j]);
count+=map.size();
}
}
System.out.println(count);
}
}
题目: