快捷搜索:

2020年 第十一届蓝桥杯第一场省赛题解(JavaC组版)

第一题:跑步训练

小明要做一个跑步训练。 初始时,小明充满体力,体力值计为 10000 。如果小明跑步,每分钟损耗 600 的体力。如果小明休息,每分钟增加 300 的体力。体力的损耗和增加都是均匀变化的。 小明打算跑一分钟、休息一分钟、再跑一分钟、再休息一分钟……如此循环。如果某个时刻小明的体力到达 0 ,他就停止锻炼。 请问小明在多久后停止锻炼。为了使答案为整数,请以秒为单位输出答案。答案中只填写数,不填写单位。 答案: 96

Scanner scanner=new Scanner(System.in);
		int n=78120;
		int sum=0;
		for(int i=1;i<=n;i++) {
          
   //注意包括自己
			if(n%i==0)sum++;
		}
		System.out.println(sum);

第二题:纪念日

小蓝有一个数字矩阵,里面只包含数字 0 和 2。小蓝很喜欢 2020,他想找到这个数字矩阵中有多少个 2020 。

• 同一行里面连续四个字符从左到右构成 2020。

• 同一列里面连续四个字符从上到下构成 2020。

• 在一条从左上到右下的斜线上连续四个字符,从左上到右下构成 2020。

例如,对于下面的矩阵: 220000

000000

002202

000000

000022

002020 一共有 5 个 2020。其中 1 个是在同一行里的,1 个是在同一列里的,3 个是斜线上的。

小蓝的矩阵比上面的矩阵要大,由于太大了,他只好将这个矩阵放在了一个文件里面,在试题目录下有一个文件 2020.txt,里面给出了小蓝的矩阵。 答案: 16520

法一:控制台输入

Scanner scanner=new Scanner(System.in);
		String[] str=new String[300];
		for(int i=0;i<300;i++) {
          
   
			str[i]=scanner.next();//输入字符
		}
		char[][] cs=new char[300][300];
		for(int i=0;i<300;i++)
			cs[i]=str[i].toCharArray();//转成char字符
		int count=0;
		for(int i=0;i<cs.length;i++) {
          
   
			for(int j=0;j<cs[i].length;j++) {
          
   
				if(cs[i][j]==2) {
          
   //三种情况判断还得判断下标越界不
					if(j+3<cs[i].length&&cs[i][j+1]==0&&cs[i][j+2]==2&&cs[i][j+3]==0)count++;
					if(i+3<cs.length&&cs[i+1][j]==0&&cs[i+2][j]==2&&cs[i+3][j]==0)count++;
					if(j+3<cs[i].length&&i+3<cs.length&&cs[i+1][j+1]==0&&cs[i+2][j+2]==2&&cs[i+3][j+3]==0)count++;
				}
			}
		}
		System.out.println(count);

法二:IO流读取

BufferedReader reader=new BufferedReader(new InputStreamReader(new FileInputStream("E:\2020.txt")));
		String[] str=new String[300];
		int k=0;
		while(reader.ready()) {
          
   //告诉这个流是否准备好被读取 结果 
			//如果下一个read()保证不阻止输入,则为True,否则为false。 请注意,返回false并不能保证下一次读取将被阻止。 
			str[k]=reader.readLine();//读一行文字
			k++;
		}
/*		while((str[k]=reader.readLine())!=null) {//这种要开301,str[301]="";
			k++;
		}*/

第三题:跑步锻炼

小蓝每天都锻炼身体。 正常情况下,小蓝每天跑 1 千米。如果某天是周一或者月初(1 日),为了激励自己,小蓝要跑 2 千米。如果同时是周一或月初,小蓝也是跑 2 千米。 小蓝跑步已经坚持了很长时间,从 2000 年 1 月 1 日周六(含)到 2020 年10 月 1 日周四(含)。请问这段时间小蓝总共跑步多少千米? 答案: 8879

public static boolean check(int year) {
          
   //判断是否为闰年
		if(year%4==0&&year%100!=0||year%400==0)return true;
		return false;
	}
	public static void main(String[] args) {
          
   
		Scanner scanner=new Scanner(System.in);
		int[] days= {
          
   0,31,28,31,30,31,30,31,31,30,31,30,31};
		int sum=0,sumday=0;//sum表示总千米,sumday表示总天数用来判断星期几
		int[] week= {
          
   0,6,7,1,2,3,4,5};
		for(int yy=2000;yy<=2020;yy++) {
          
   //遍历年份
			for(int mm=1;mm<=12;mm++) {
          
   //遍历月份
				int day=days[mm];
				if(check(yy)&&mm==2)day++;//是闰年则2月多一天
				for(int dd=1;dd<=day;dd++) {
          
   //遍历月份每一天
					sumday++;
					if(yy==2020&&mm==10&&dd==1) {
          
   //如果是最后一天
						sum+=2;
						System.out.println(sum);
						return;
					}
					else if(dd==1||sumday%7==3)sum+=2;//如果是周一或者是星期一则加总千米二
					else sum++;//其余情况加一
				}
			}
		}
	}

第四题:平面分割(未解)

20 个圆和 20 条直线最多能把平面分成多少个部分? 答案:

第五题:七段码(未解)

不会 答案:

第六题:成绩统计

小蓝给学生们组织了一场考试,卷面总分为 100 分,每个学生的得分都是一个 0 到 100 的整数。 如果得分至少是 60 分,则称为及格。如果得分至少为 85 分,则称为优秀。 请计算及格率和优秀率,用百分数表示,百分号前的部分四舍五入保留整数。 输入格式: 输入的第一行包含一个整数 n,表示考试人数。 接下来 n 行,每行包含一个 0 至 100 的整数,表示一个学生的得分。 输出格式: 输出两行,每行一个百分数,分别表示及格率和优秀率。百分号前的部分四舍五入保留整数。 样例输入: 7 80 92 56 74 88 100 0 样例输出: 71% 43% 评测用例规模与规定: 对于 50% 的评测用例,1 ≤ n ≤ 100。 对于所有评测用例,1 ≤ n ≤ 10000。 答案:

//坑点:
		//其实题目思路很简单,但是千万不要大意,各种情况都得考虑好
		Scanner scanner=new Scanner(System.in);
		int n=scanner.nextInt();
		double jige=0;//有小数
		double youxiu=0;
		for(int i=0;i<n;i++) {
          
   
			int k=scanner.nextInt();
			if(k>=60)jige ++;//及格人数
			if(k>=85)youxiu ++;//优秀人数
		}
		String a=String.format("%.2f", jige/n);//四舍五入并且保留两位小数
		String b=String.format("%.2f", youxiu/n);
		int beginIndex=2;
		if(n==jige)System.out.println("100%");//若全部及格
		else{
          
   
		    	if(a.charAt(2)==0)beginIndex=3;//若及格率小于10%
		        System.out.println(a.substring(2,4)+"%");
		}
        if(youxiu==n)System.out.println("100%");
        else{
          
   
            if(b.charAt(2)==0)beginIndex=3;
		    System.out.println(b.substring(beginIndex,4)+"%");
        }

第七题:单词分析

小蓝正在学习一门神奇的语言,这门语言中的单词都是由小写英文字母组成,有些单词很长,远远超过正常英文单词的长度。小蓝学了很长时间也记不住一些单词,他准备不再完全记忆这些单词,而是根据单词中哪个字母出现得最多来分辨单词。

现在,请你帮助小蓝,给了一个单词后,帮助他找到出现最多的字母和这个字母出现的次数。 输入格式: 输入一行包含一个单词,单词只由小写英文字母组成。 输出格式: 输出两行,第一行包含一个英文字母,表示单词中出现得最多的字母是哪 个。如果有多个字母出现的次数相等,输出字典序最小的那个。 第二行包含一个整数,表示出现得最多的那个字母在单词中出现的次数 样例输入: lanqiao 样例输出: a 2 样例输入: longlonglongistoolong 样例输出: o 6

答案:

//用哈希表计算即可
		//坑点:注意不要看漏题意(如果有多个字母出现的次数相等,输出字典序最小的那个。)这限制条件很常见
		//System.err:“标准”错误输出流
		Scanner scanner=new Scanner(System.in);
		int[] hash=new int[1010];
		String string=scanner.next();
		int  idx = 0;
		int max=0;
		for(int i=0;i<string.length();i++) {
          
   
			int j=string.charAt(i)-0;//把a=48的转为数字表示
			hash[j]++;//该字母的hash值加一
			if(max<hash[j]||max==hash[j]&&idx>j) {
          
   
				max=hash[j];
				idx=j;//出现最多的字母下标
			}
		}
		System.out.println((char)idx);//把数字转为字母
		System.out.println(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 答案:

思路:这题就是一道经典的线性DP题

//线性DP
		Scanner scanner=new Scanner(System.in);
		int N=110;
		int[][] g=new int[N][N];//容量比数据要求的大一些
		int[][] f=new int[N][N];//表示所有从(1,1)走到(i,j)的合法路线集合,值存储的是所有路线中和最大的
		int n=scanner.nextInt();
		for(int i=1;i<=n;i++) {
          
   
			for(int j=1;j<=i;j++) {
          
   
				g[i][j]=scanner.nextInt();
			}
		}
		
		for(int i=0;i<N;i++) {
          
   
			for(int j=0;j<N;j++)
				f[i][j]=Integer.MIN_VALUE;//题目求最大值,先初始化为最小值(表示负无穷),同时可以表示边界
		}
		f[1][1]=g[1][1];
		for(int i=2;i<=n;i++) {
          
   
			for(int j=1;j<=i;j++) {
          
   
				//最好情况下可以从两个地方走,也有可能只能一个地方走到,另一个不存在但没关系,不存在的已经初始为最小值不会取到
				f[i][j]=Math.max(f[i-1][j-1], f[i-1][j])+g[i][j];
			}
		}
		//由于题目是说向左下走的次数与向右下走的次数相差不能超过 1。说明最后一步必须是底层的中位数
		if(n%2==0)System.out.println(Math.max(f[n][n/2], f[n][n/2-1]));//比较偶数个的两个中间数
		else System.out.println(f[n][n/2+1]);//奇数只有一个

第九题:作物杂交

作物杂交是作物栽培中重要的一步。已知有 N 种作物 (编号 1 至 N ),第i 种作物从播种到成熟的时间为 Ti。作物之间两两可以进行杂交,杂交时间取两种中时间较长的一方。

如作物 A 种植时间为 5 天,作物 B 种植时间为 7 天,则 AB 杂交花费的时间为 7 天。作物杂交会产生固定的作物,新产生的作物仍然属于 N 种作物中的一种。

初始时,拥有其中 M 种作物的种子 (数量无限,可以支持多次杂交)。同时可以进行多个杂交过程。求问对于给定的目标种子,最少需要多少天能够得到。

如存在 4 种作物 ABCD,各自的成熟时间为 5 天、7 天、3 天、8 天。初始拥有 AB 两种作物的种子,目标种子为 D,已知杂交情况为 A × B → C,A × C → D。则最短的杂交过程为: 第 1 天到第 7 天 (作物 B 的时间),A × B → C。 第 8 天到第 12 天 (作物 A 的时间),A × C → D。 花费 12 天得到作物 D 的种子。 输入格式: 输入的第 1 行包含 4 个整数 N, M, K, T,N 表示作物种类总数 (编号 1 至N),M 表示初始拥有的作物种子类型数量,K 表示可以杂交的方案数,T 表示目标种子的编号。 第 2 行包含 N 个整数,其中第 i 个整数表示第 i 种作物的种植时间Ti(1 ≤ Ti ≤ 100)。 第 3 行包含 M 个整数,分别表示已拥有的种子类型 Kj(1 ≤ Kj ≤ M),Kj两两不同。 第 4 至 K + 3 行,每行包含 3 个整数 A, B,C,表示第 A 类作物和第 B 类作物杂交可以获得第 C 类作物的种子。 输出格式: 输出一个整数,表示得到目标种子的最短杂交时间。 样例输入: 6 2 4 6 5 3 4 6 4 9 1 2 1 2 3 1 3 4 2 3 5 4 5 6 样例输出: 16 样例说明: 第 1 天至第 5 天,将编号 1 与编号 2 的作物杂交,得到编号 3 的作物种子。 第 6 天至第 10 天,将编号 1 与编号 3 的作物杂交,得到编号 4 的作物种子。 第 6 天至第 9 天,将编号 2 与编号 3 的作物杂交,得到编号 5 的作物种子。 第 11 天至第 16 天,将编号 4 与编号 5 的作物杂交,得到编号 6 的作物种子。 总共花费 16 天。 评测用例规模与规定: 对于所有评测用例,1 ≤ N ≤ 2000, 2 ≤ M ≤ N, 1 ≤ K ≤ 100000, 1 ≤ T ≤ N,保证目标种子一定可以通过杂交得到。 答案:

没测试点暂时不做

第十题:子串分值和

对于一个字符串 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。 输出格式: 输出一个整数表示答案。 样例输入: 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。 答案:

//只想到用hashset去重,时间复杂n^2,会超时不过一半分拿下也不错了
        Scanner sc = new Scanner(System.in);
        String string=sc.next();
        int res=0;
        for(int i=0;i<string.length();i++) {
          
   //字串起点
            HashSet<Character> hashSet=new HashSet<>();//可以去重
            for(int j=i;j<string.length();j++) {
          
   
                hashSet.add(string.charAt(j));
                res+=hashSet.size();//去重后的个数就是分数
            }
        }
        System.out.println(res);
经验分享 程序员 职场和发展