文章目录
第一题:跑步训练
小明要做一个跑步训练。
初始时,小明充满体力,体力值计为 10000 。如果小明跑步,每分钟损耗 600 的体力。如果小明休息,每分钟增加 300 的体力。体力的损耗和增加都是均匀变化的。
小明打算跑一分钟、休息一分钟、再跑一分钟、再休息一分钟……如此循环。如果某个时刻小明的体力到达 0 ,他就停止锻炼。
请问小明在多久后停止锻炼。为了使答案为整数,请以秒为单位输出答案。答案中只填写数,不填写单位。
答案: 96
Scanner scanner=new Scanner(System.in);
int sum=10000;
int time=0;
while(sum>=600) {//当体力大于600
sum-=600;//消耗600体力
time++;
sum+=300;//休息增加300体力
time++;
}
//最后还剩400体力 由于他说是均匀变化的,则10秒消耗100体力
int k=sum/10;
time=time*60+k;
System.out.println(time);
第二题:纪念日
小蓝有一个数字矩阵,里面只包含数字 0 和 2。小蓝很喜欢 2020,他想找到这个数字矩阵中有多少个 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++;
}*/
第三题:合并检测
新冠疫情由新冠病毒引起,最近在 A 国蔓延,为了尽快控制疫情,A 国准备给大量民众进病毒核酸检测。然而,用于检测的试剂盒紧缺。为了解决这一困难,科学家想了一个办法:合并检测。即将从多个人(k个)采集的标本放到同一个试剂盒中进行检测。如果结果为阴性,则说明这 k个人都是阴性,用一个试剂盒完成了 k 个人的检测。如果结果为阳性,则说明至少有一个人为阳性,需要将这 k 个人的样本全部重新独立检测(从理论上看,如果检测前 k - 1 个人都是阴性可以推断出第 k 个人是阳性,但是在实际操作中不会利用此推断,而是将 k 个人独立检测),加上最开始的合并检测,一共使用了 k + 1 个试剂盒完成了 k 个人的检测。
A 国估计被测的民众的感染率大概是 1%,呈均匀分布。请问 k 取多少能最节省试剂盒?
答案: 10
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++;//其余情况加一
}
}
}
}
第四题:REPEAT程序
附件 prog.txt 中是一个用某种语言写的程序。其中 REPEAT k 表示一个次数为 k 的循环。循环控制的范围由缩进表达,从次行开始连续的缩进比该行多的(前面的空白更长的)为循环包含的内容。
例如如下片段:
REPEAT 2:
A = A + 4
REPEAT 5:
REPEAT 6:
A = A + 5
A = A + 7
A = A + 8
A = A + 9
该片段中从 A = A + 4 所在的行到 A = A + 8 所在的行都在第一行的循环两次中。
REPEAT 6: 所在的行到 A = A + 7 所在的行都在 REPEAT 5: 循环中。
A = A + 5 实际总共的循环次数是 2 × 5 × 6 = 60 次。
请问该程序执行完毕之后,A 的值是多少?
答案: 241830
第五题:矩阵
把 1 ∼ 2020 放在 2 × 1010 的矩阵里。要求同一行中右边的比左边大,同一列中下边的比上边的大。一共有多少种方案?答案很大,你只需要给出方案数除以 2020 的余数即可。
答案: 1340
第六题:整除序列
有一个序列,序列的第一个数是 n,后面的每个数是前一个数整除 2,请输出这个序列中值为正数的项。
输入格式:
输入一行包含一个整数 n。
输出格式:
输出一行,包含多个整数,相邻的整数之间用一个空格分隔,表示答案。
样例输入:
20
样例输出:
20 10 5 2 1
评测用例规模与规定:
对于 80% 的评测用例,1 ≤ n ≤ 109
对于所有评测用例,1 ≤ n ≤ 1018
答案:
第七题:解码
小蓝正在学习一门神奇的语言,这门语言中的单词都是由小写英文字母组成,有些单词很长,远远超过正常英文单词的长度。小蓝学了很长时间也记不住一些单词,他准备不再完全记忆这些单词,而是根据单词中哪个字母出现得最多来分辨单词。
现在,请你帮助小蓝,给了一个单词后,帮助他找到出现最多的字母和这个字母出现的次数。
输入格式:
输入一行包含一个单词,单词只由小写英文字母组成。
输出格式:
输出两行,第一行包含一个英文字母,表示单词中出现得最多的字母是哪
个。如果有多个字母出现的次数相等,输出字典序最小的那个。
第二行包含一个整数,表示出现得最多的那个字母在单词中出现的次数
样例输入:
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 至第 m 列,每一个点可以用行号和列号来表示。现在有个人站在第 1 行第 1 列,要走到第 n 行第 m 列。只能向右或者向下走。注意,如果行号和列数都是偶数,不能走入这一格中。问有多少种方案。
输入格式:
输入一行包含两个整数 n, m。
输出格式:
输出一个整数,表示答案。
样例输入:
3 4
样例输出:
2
样例输入:
6 6
样例输出:
0
评测用例规模与规定:
对于所有评测用例,1 ≤ n ≤ 30, 1 ≤ m ≤ 30。
答案:
思路:这题就是一道经典的线性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 的数组 A1, A2, · · · , An。你可以从中选出两个数 Ai 和 Aj (i 不等于 j),然后将 Ai 和 Aj 一前一后拼成一个新的整数。例如 12 和 345 可以拼成 12345 或 34512。注意交换 Ai 和 Aj 的顺序总是被视为 2 种拼法,即便是 Ai = Aj 时。请你计算有多少种拼法满足拼出的整数是 K 的倍数。
输入格式:
第一行包含 2 个整数 n 和 K。
第二行包含 n 个整数 A1, A2, · · · , An。
输出格式:
一个整数代表答案。
样例输入:
4 2
1 2 3 4
样例输出:
6
样例说明:
第 1 天至第 5 天,将编号 1 与编号 2 的作物杂交,得到编号 3 的作物种子。
第 6 天至第 10 天,将编号 1 与编号 3 的作物杂交,得到编号 4 的作物种子。
第 6 天至第 9 天,将编号 2 与编号 3 的作物杂交,得到编号 5 的作物种子。
第 11 天至第 16 天,将编号 4 与编号 5 的作物杂交,得到编号 6 的作物种子。
总共花费 16 天。
评测用例规模与规定:
对于 30% 的评测用例,1 ≤ n ≤ 1000, 1 ≤ K ≤ 20, 1 ≤ Ai ≤ 104。
对于所有评测用例,1 ≤ n ≤ 10的5,1 ≤ K ≤ 10的5,1 ≤ Ai ≤ 10的9。
答案:
第十题:网络分析
小明正在做一个网络实验。他设置了 n 台电脑,称为节点,用于收发和存储数据。初始时,所有节点都是独立的,不存在任何连接。小明可以通过网线将两个节点连接起来,连接后两个节点就可以互相通信了。两个节点如果存在网线连接,称为相邻。小明有时会测试当时的网络,他会在某个节点发送一条信息,信息会发送到每个相邻的节点,之后这些节点又会转发到自己相邻的节点,直到所有直接或间接相邻的节点都收到了信息。所有发送和接收的节点都会将信息存储下来。一条信息只存储一次。给出小明连接和测试的过程,请计算出每个节点存储信息的大小。
输入格式:
输入的第一行包含两个整数 n, m,分别表示节点数量和操作数量。节点从1 至 n 编号。
接下来 m 行,每行三个整数,表示一个操作。
如果操作为 1 a b,表示将节点 a 和节点 b 通过网线连接起来。当 a = b时,表示连接了一个自环,对网络没有实质影响。
如果操作为 2 p t,表示在节点 p 上发送一条大小为 t 的信息。
输出格式:
输出一行,包含 n 个整数,相邻整数之间用一个空格分割,依次表示进行
完上述操作后节点 1 至节点 n 上存储信息的大小。
样例输入:
4 8
1 1 2
2 1 10
2 3 5
1 4 1
2 2 2
1 1 2
1 2 4
2 2 1
样例输出:
13 13 5 3
评测用例规模与约定:
对于 30% 的评测用例,1 ≤ n ≤ 20,1 ≤ m ≤ 100。
对于 50% 的评测用例,1 ≤ n ≤ 100,1 ≤ m ≤ 1000。
对于 70% 的评测用例,1 ≤ n ≤ 1000,1 ≤ m ≤ 10000。
对于所有评测用例,1 ≤ n ≤ 10000,1 ≤ m ≤ 100000,1 ≤ t ≤ 100。
答案: