第十一届蓝桥杯Java C组 省赛真题(2)

试题 D: 合并检测

本题总分:10 分

【问题描述】

最近存在A病,最近在 A 国蔓延,为了尽快控制病*,A 国准备给大量民众进病*检测。

然而,用于检测的试剂盒紧缺。

为了解决这一困难,科学家想了一个办法:合并检测。即将从多个人(k个)采集的标本放到同一个试剂盒中进行检测。如果结果为阴性,则说明这 k个人都是阴性,用一个试剂盒完成了 k 个人的检测。如果结果为阳性,则说明至少有一个人为阳性,需要将这 k 个人的样本全部重新独立检测(从理论上看,如果检测前 k 1 个人都是阴性可以推断出第 k 个人是阳性,但是在实际操作中不会利用此推断,而是将 k 个人独立检测),加上最开始的合并检测,一共使用了 k + 1 个试剂盒完成了 k 个人的检测。
A 国估计被测的民众的感染率大概是 1%,呈均匀分布。请问 k 取多少能最节省试剂盒?

【答案提交】

这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

【解题思路】
这道题的问题:

  1. A国的人数,这个就是定义一个变量allPerson,去假定一个人数,eg:100,10000,782等等
  2. 多个标本k放到同一个试剂盒中的k如何定义。k的最小值就是1,就是一个人一个试剂盒的情况,这也是最好的情况了,k的范围在(1 ~ allPerson),其实k也不可能为总人数,就是所有人用一个试剂盒的情况,这个肯定不现实。但由于检测的试剂盒紧缺,所以k不可能太小,也不可能太大,这个我们就可以定一个合理的范围(1 ~ 100)即可
  3. 测出感染后需要使用的试剂盒数量,因为它感染的人那个试剂盒内的k个标本要通过k个试剂盒单个检验。已知的是感染率是1%,而且感染的人是平均分布的,所以不用去考虑几个感染在一块儿的情况。所以测出感染后需要使用的试剂盒数量 = (1% × 人数)× k ;其中(1% × 人数) 得到的感染人数,并且感染人数肯定是一个整数,这里就需要通过进行向上取整或向下取整来得到感染人数。
  4. 人数能否被k整除。因为能整除的话,(人数/k)就相当于几个试剂盒。如果不能整除的话,那么它的试剂盒需要再+1用来测试最后剩下来的人的感染情况(剩下的人数肯定是小于8的),我们不需要去考虑剩下的人存在感染情况的可能,因为前面的(0.01人数k)得到的已经是最大的测出感染后需要使用的试剂盒。

解题思路如下:

  1. 假定A国人数,定义试剂盒个数,试剂盒最小个数,以及最后结果
  2. k标本再定义范围内的循环,看几个标本使用一个试剂盒最合适
  3. 判断(人数/k)能否被整除(即人数%k是否=0)
  4. 能整除的试剂盒个数 = (人数/ k) + (int) Math.floor(0.01 * 人数) * k;
  5. 不能整除的试剂盒个数 = (人数/ k) + (int) Math.floor(0.01 * 人数) * k + 1;
  6. 判断出最小最合适的情况即可

【代码如下】

/**
 * 估计被测的民众的感染率大概是 1%,呈均匀分布。请问 k 取多少能最节省试剂盒?
 * 
 * @author hf
 *
 */
public class Blogs3 {
	public static void main(String[] args) {
		int allPerson = 999; // 随机确定的人数
		int num = 0; // 试剂盒的个数
		int minx = 9999999; // 试剂盒最少的个数
		int answer = 0; // 答案
		
		for (int k = 1; k <= allPerson; k++) {
			if (allPerson % k == 0) {
				num = (allPerson / k) + (int) Math.floor(0.01 * allPerson) * k;
			} else {
				num = (allPerson / k) + (int) Math.floor(0.01 * allPerson) * k + 1;
			}
			// 判断出最小试剂盒的情况就ok了
			if (num < minx) {
				minx = num;
				// System.out.println(num);
				answer = k;
			}
		}
		System.out.println(answer);
	}
}

【填空结果】
在这里插入图片描述

试题 E: REPEAT 程序

本题总分:15 分

【问题描述】

附件 prog.txt 中是一个用某种语言写的程序。

其中 REPEAT k 表示一个次数为 k 的循环。循环控制的范围由缩进表达,

从次行开始连续的缩进比该行多的(前面的空白更长的)为循环包含的内容。

例如如下片段:

在这里插入图片描述

该片段中从A = A + 4 所在的行到 A = A + 8 所在的行都在第一行的循环两次中。

REPEAT 6: 所在的行到 A = A + 7 所在的行都在 REPEAT 5: 循环中。

A = A + 5 实际总共的循环次数是 2 × 5 × 6 = 60 次。

请问该程序执行完毕之后,A 的值是多少?

【答案提交】

这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个

整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

【解题思路】
这道题按照给的循环嵌套格式将代码写出来,最后直接打印就可以了。
因为这到题上面它提示到 A = A + 5 实际总共的循环次数是 2 × 5 × 6 = 60 次。这个就打消了让手算的可能。

【代码如下】

/**
 * 试题 E: REPEAT 程序
 * @author hf
 *
 */
public class Blogs4 {
	public static void main(String[] args) {
		int A = 0; //a的值
		for (int i = 0; i < 2; i++) {
			A += 4;
			for (int j = 0; j < 5; j++) {
				for (int k = 0; k < 6; k++) {
					A += 5;
				}
				A += 7;
			}
			A += 8;
		}
		A += 9;
		
		System.out.println(A);
	}
}

【填空结果】
在这里插入图片描述

试题 F: 分类计数

本题总分:15 分

【问题描述】

输入一个字符串,请输出这个字符串包含多少个大写字母,多少个小写字母,多少个数字。

【输入格式】

输入一行包含一个字符串。

【输出格式】

输出三行,每行一个整数,分别表示大写字母、小写字母和数字的个数。

【样例输入】

1+a=Aab

【样例输出】

1
3
1

【解题思路】
这道题不难,思路如下:

  1. 先将输入的字符串通过.toCharArray()变成字符数组
  2. 定义一个数组来进行统计大写字母、小写字母和数字的个数
  3. 循环数组并通过ASCII码或者直接的范围(0 ~ 9;a ~ z;A ~ Z)进行判断
  4. 判断出来就在对应的下标上+1
  5. 最后遍历打印

【代码如下】

import java.util.Scanner;

/**
 * 输入一个字符串,请输出这个字符串包含多少个大写字母,多少个小写字母,多少个数字。
 * @author hf
 *
 */
public class Blogs5 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String str = sc.next();
		char [] ch = str.toCharArray();
		int [] num = new int [3];
		for (int i = 0; i < ch.length; i++) {
			if (ch[i] >= '0' && ch[i] <= '9') {
				num[2]++;
			}else if (ch[i] >= 'a' && ch[i] <= 'z') {
				num[1]++;
			}else if (ch[i] >= 'A' && ch[i] <= 'Z') {
				num[0]++;
			}
		}
		for (int i : num) {
			System.out.println(i);
		}
		sc.close();
	}
}

【样例结果】
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_45481524/article/details/107370188