花花生米

导航

2020第十一届蓝桥杯第二场JavaB组

第一题:门牌制作(624)

题目大意:

  • 判断1到2020里面共有多少个‘2’;

解析:

  • 本题简而言之就是找‘2’这一个数
  • 第一种方法:遍历将其转换为字符然后再遍历寻找
  • 第二种方法:直接用数值的方法进行计算

以下为运行成功的代码 :

/*
 * 第一题:判断1到2020里面共有多少个‘2’
 * @又又
 */

/*
 * 第一种方法:先将其转换为字符,然后再遍历寻找
 * 第二种:直接用数值的方法进行计算
 */
//public class test01 {
//
//	public static void main(String[] args) {
//		// TODO Auto-generated method stub
//
//		int ans=0;
//		char ch[] = null;
//		for (int i = 1; i <=2020; i++) {
//			ch=Integer.toString(i).toCharArray();
//			for (int j = 0; j < ch.length; j++) {
//				if(ch[j]=='2')
//					ans++;
//			}
//		}
//		System.out.println(ans);
//	}
//
//}


public class test01{
	public static void main(String[] args) {
		int ans=0;
		for (int i = 1,n=1; i <=2020;n=++i) {
			do {
				if(n%10==2)
					ans++;
			}
			while((n/=10)>0);
		}
		System.out.println(ans);
	}
}

第二题:寻找2020(16520)

题目大意:

  • 简而言之即:在一个数字矩阵里面找2020,同一行从左到右,同一列从上到下,斜线上左上到右下构成

解析:

  • 在输入数据的时候可以采用原始的方式从键盘输入,或者熟悉输入流导入
  • 层层暴力遍历寻找满足条件的数,感觉暴力出奇迹哈哈哈

以下是运行成功的代码:

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;

/*
 * 寻找2020,在一个数字矩阵里找2020,同一行从左到右,同一列
 * 从上到下,斜线上左上到右下构成
 * @又又
 */
import java.util.Scanner;

public class test02{

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner in = new Scanner(System.in);//采用的直接从键盘输入方式
        int[][] num = new int[305][305];
        for (int i=1;i<=300;i++) {
            String str = in.next();
            for (int j=1;j<=str.length();j++) {
                num[i][j] = str.charAt(j-1) - '0';//得到相应的整数
            }
        }
        
        int ans = 0;
        for (int i=1;i<=300;i++) {
            for (int j=1;j<=300;j++) {
                if (i+3<=300 && num[i][j]==2 && num[i+1][j]==0 && num[i+2][j]==2 && num[i+3][j]==0)
                    ans++;
            }
        }
        
        for (int i=1;i<=300;i++) {
            for (int j=1;j<=300;j++) {
                if (j+3<=300 && num[i][j]==2 && num[i][j+1]==0 && num[i][j+2]==2 && num[i][j+3]==0)
                    ans++;
            }
        }
        
        for (int i=1;i<=300;i++) {
            for (int j=1;j<=300;j++) {
                if (i+3<=300 && j+3<=300 && num[i][j]==2 && num[i+1][j+1]==0 && num[i+2][j+2]==2 && num[i+3][j+3]==0)
                    ans++;
            }
        }
        System.out.println(ans);

    }
}

第三题:蛇形填数(761)

题目大意:

  • 根据以下的图形以及数值,我们可以知道第二行第二列的数值为5,现在求第20行第20列的数值为多少?
 /*
 * 蛇形填数:
 * 1  2  6  7  15 ...
 * 3  5  8  14 ...
 * 4  9  13 ...
 * 10 12 ...
 * 11 ...
 * ...
 * 
 * @ac
 */

解析:

找规律:
 
 行列(a)    第i行第i列的那个数值前面有几条斜线(b)     所在位置的数值(c)
 
 
 a        b          c
 1        1          1 
 2        2          5
 3        4          13
 4        6          25 
 5        8          41
 6        10         61
 ...      ...        ...
 20      20*2-2      20*38+1=761
 
 解析:
 发现a与b的关系为a*2-2=b
 从2开始这三者的关系为:a*b+1=c

第六题:成绩分析

题目大意

/*
 * 成绩分析:
 * 求最高分、最低分、平均分
 * 
 * 输入格式:
 * 第一行一个整数n,表示考试人数
 * 接下里n行,每行包含一个0到100的整数,表示一个学生的得分
 * 
 * 输出格式:
 * 输出三行
 * 第一行一个整数表示最高分
 * 第二行一个整数表示最低分
 * 第三行一个实数、四舍五入保留正好两位小数,表示平均分
 */

以下为运行成功的代码:

import java.util.Arrays;
import java.util.Scanner;

/*
 * 成绩分析:
 * 求最高分、最低分、平均分
 * 
 * 输入格式:
 * 第一行一个整数n,表示考试人数
 * 接下里n行,每行包含一个0到100的整数,表示一个学生的得分
 * 
 * 输出格式:
 * 输出三行
 * 第一行一个整数表示最高分
 * 第二行一个整数表示最低分
 * 第三行一个实数、四舍五入保留正好两位小数,表示平均分
 */
public class test06 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner in=new Scanner (System.in);
		int n=in.nextInt();int a;
		int max=Integer.MIN_VALUE,min=Integer.MAX_VALUE;
		double sum=0;
		for (int i = 0; i < n; i++) {
			a=in.nextInt();
			sum+=a;
			if(a>max)
				max=a;
			if(min>a)
				min=a;
		}
		
		System.out.println(max);
		System.out.println(min);
		System.out.println(String.format("%.2f",sum/n));
	}

}

第七题:单词分析

题目大意:

  • 输入一行字母,然后从中找出出现次数最多的字母,以及他出现的次数,如果有多个次数相同的字母,则按照字典序输出
  • 输出格式:第一行输出字母,第二行输出次数

解析:

  • 1.因为题目已经要求了全部是小写字母的输入,所以我们就不需要考虑大小写字母的转换问题了
  • 2.第一步,因为要确定字母出现的次数,先将输入的一行字母转换为字符数组
ch=str.toCharArray();
  • 3.第二步,遍历统计次数,字符-'a'
  • 4.第三步,判断最大次数以及转换为字符输出

以下为运行成功的代码:

import java.util.Scanner;

/*
 * 单词分析:
 * 在输入到 一行单词中,找出出现次数最多的字母是哪一个,如果有多个一样的,则输出字典序最小的那一个
 * 第一行输出字母
 * 第二行输出次数
 * 
 * @又又
 */
public class test07 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner in=new Scanner (System.in);
		String str=in.nextLine();
		char ch[]=new char[26];
		int ans[]=new int[26];
		ch=str.toCharArray();
		/*
		 * 统计字母出现次数
		 * a:97
		 */
		for (int i = 0; i < ch.length; i++) {
			ans[ch[i]-'a']++;
		}
		char zimu = 0;
		int max=Integer.MIN_VALUE;
		for (int i = 0; i < ans.length; i++) {
			if(max<ans[i])
			{
				max=ans[i];//最大次数
				zimu=(char)(i+'a');//转换为字符/字母
			}
		}
		System.out.println(zimu+"\n"+max);
	}

}

第八题:数字三角形

题目大意:


从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和。路径上的每一步只能从一个数走到下一层和它最近的左边的那个数或者右边的那个数。此外,向左下走的次数与向右下走的次数相差不能超过 1。

输入格式:
输入的第一行包含一个整数 N (1 < N ≤ 100),表示三角形的行数。下面的N 行给出数字三角形。数字三角形上的数都是 0 至 100 之间的整数。

输出格式:
输出一个整数,表示答案。

样例:

5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5

答案输出:
27

解析:

  • 1.此题跟数字保龄球的思想大致一样,直接dp数组一套操作下来差不多,但是这里需要注意的是,此题要求了向左走和向右走的次数相差不能超过1.
  • 2.其实好像没分清这个写法是不是经典dp哈哈哈哈,那就当作暴力解法,毕竟暴力出奇迹
  • 3.在递归选择向左走和向右走以至于达到最大和的时候,还应判断二者次数的相差值,所以直接可以将这四者(向左,向右,向左走的次数,向右走的次数)函数递归;
  • 4.在每次的函数递归的时候,先判断上次二者的次数相差值;

突然想起在比赛的时候好像最后真就直接rua的dp,兀突突

以下为运行成功的代码:

import java.util.Scanner;

/*
 * 数字三角形
 * @又又⭐
 */
public class test08 {
	static int max=Integer.MIN_VALUE;
	static Scanner in =new Scanner (System.in);
	static int n=in.nextInt();
	static int ans[][]=new int [n][n];
	
	public static int bl(int ans[][],int i,int j,int left,int right)
	{
		if(i==ans.length-1)
		{
			if(Math.abs(left-right)>1)
				return 0;
		}
		if(i<ans.length)
		{
			return ans[i][j]+Math.max(bl(ans, i+1,j+1,left,right+1),bl(ans,i+1,j,left+1,right));
		}
		return 0;
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		for (int i = 0; i < n; i++) {
			for (int j = 0; j <=i; j++) {
				ans[i][j]=in.nextInt();
			}
		}
		System.out.println(bl(ans,0,0,0,0));
	}

}

第九题:子串分值和

题目大意:

时间限制: 1.0s 内存限制: 512.0MB 本题总分:25 分
对于一个字符串 S,我们定义 S 的分值 f(S ) 为 S 中出现的不同的字符个数。例如 f(”aba”) = 2,f(”abc”) = 3, f(”aaa”) = 1。现在给定一个字符串 S [0…n n 1](长度为 n),请你计算对于所有 S 的非空
子串 S [i… j](0 ≤ i ≤ j < n),f(S [i… j]) 的和是多少。
输入格式:
输入一行包含一个由小写字母组成的字符串 S。
输出格式:
输出一个整数表示答案。
样例输入:
ababc
样例输出:
28

评测用例规模与约定:
对于 20% 的评测用例,1 ≤ n ≤ 10;
对于 40% 的评测用例,1 ≤ n ≤ 100;
对于 50% 的评测用例,1 ≤ n ≤ 1000;
对于 60% 的评测用例,1 ≤ n ≤ 10000;
对于所有评测用例,1 ≤ n ≤ 100000。

样例解析:

解析:

  • 1.题目的大概意思即划分出子串,然后在子串中找出出现的不同字母的个数,然后将其相加即可得出答案;
  • 2.既然要求包含不同字母,可以想到用set集合,每个字母的出现只会算作一次;
  • 3.用两个for循环(前提需要判断时间复杂度是否满足题目要求),在第二个循环中依次将其add进set中,然后相加set.size()次数;

以下是运行成功的代码:

import java.util.HashSet;
import java.util.Scanner;

/*
 * 子串分值和
 */
public class test09 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner in=new Scanner(System.in);
		String str=in.nextLine();
		char ch[]=str.toCharArray();
		long ans=0;
		for (int i = 0; i < ch.length; i++) {
			HashSet<Character> set=new HashSet<Character>();
			for (int j = i; j < ch.length; j++) {
				set.add(ch[j]);
				ans+=set.size();
			}
		}
		System.out.println(ans);
	}

}

posted on 2021-02-03 11:08  花花生米  阅读(1345)  评论(0编辑  收藏  举报