成绩分析
题目描述
成绩分析
小蓝给学生们组织了一场考试,卷面总分为 100 分,每个学生的得分都是
一个 0 到 100 的整数。
请计算这次考试的最高分、最低分和平均分。
输入格式
输入的第一行包含一个整数 n,表示考试人数。
接下来 n 行,每行包含一个 0 至 100 的整数,表示一个学生的得分。
输出格式
输出三行
第一行包含一个整数,表示最高分。
第二行包含一个整数,表示最低分。
第三行包含一个实数,四舍五入保留正好两位小数,表示平均分。
输入
7
80
92
56
74
88
99
10
输出
99
10
71.29
这题没什么好说的,直接写就行了,不过需要注意的是,平均成绩是要保留两位小数的,可以直接用格式化输出System.out.printf("%.2f",sum/n);
。复杂一点的位数保留问题需要用到别的类了,这个等过一两天再写。
现在写好了,小数位的取舍方法
public class Main{
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int[]score=new int[n];
for(int i=0;i<n;i++) {
score[i]=sc.nextInt();
}
int max=score[0];
int min=max;
float sum=0;
for(int i:score) {
if(i>max)max=i;
if(i<min)min=i;
sum+=i;
}
System.out.println(max);
System.out.println(min);
System.out.printf("%.2f",sum/n);
sc.close();
}
}
单词分析
小蓝正在学习一门神奇的语言,这门语言中的单词都是由小写英文字母组
成,有些单词很长,远远超过正常英文单词的长度。小蓝学了很长时间也记不
住一些单词,他准备不再完全记忆这些单词,而是根据单词中哪个字母出现得
最多来分辨单词。
现在,请你帮助小蓝,给了一个单词后,帮助他找到出现最多的字母和这
个字母出现的次数。
时间限制: 1.0s
内存限制: 512.0MB
本题总分:20 分
输入格式
输入一行包含一个单词,单词只由小写英文字母组成。
输出格式
输出两行,第一行包含一个英文字母,表示单词中出现得最多的字母是哪
个。如果有多个字母出现的次数相等,输出字典序最小的那个。
第二行包含一个整数,表示出现得最多的那个字母在单词中出现的次数。
输入样例
lanqiao
输出样例
a
2
输入样例
longlonglongistoolong
输出样例
o
6
思路很清楚,我们用一个长度为26的数组保存26个英语字母,每出现一次就++,得到最后的数据,就可以找到最大出现次数的下标,输出就行了,这里注意char和int的转化就行。0的ASCII码表对应的是48,A对应65,a对应97。但是我们这里直接用’a’就行,简单实用。
public class Main{
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
String str = sc.nextLine();
int[] chars=new int[26];
for(char i:str.toCharArray()) {
chars[i-'a']++;
}
int max=0,maxIndex=0;
for(int i=0;i<26;i++) {
if(chars[i]>max) {
max=chars[i];
maxIndex=i;
}
}
System.out.println((char)(maxIndex+'a'));
System.out.println(max);
sc.close();
}
}
数字三角形
上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。
对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和。
路径上的每一步只能从一个数走到下一层和它最近的左边的那个数或者右边的那个数。此外,向左下走的次数与向右下走的次数相差不能超过 1。
时间限制: 1.0s 内存限制: 512.0MB 本题总分:20 分
输入格式
输入的第一行包含一个整数 N (1 < N ≤ 100),表示三角形的行数。下面的N 行给出数字三角形。数字三角形上的数都是 0 至 100 之间的整数
输出格式
输出一个整数
输入样例
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
输出样例
27
这题也是直接暴力递归就行,dfs,我原本想用栈来写递归来着,但是实力不够,哈哈😂,最后还是用递归去写了。注意点如下
- 到最下面一层的时候再判断左右走过的次数
- 其他的好像没什么了。
递归版
public class Main{
static List <Position>list=new ArrayList<>();
static int max=0;
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int[][]map=new int[n][n];
for(int i=0,next=0;i<n;i++,next++) {
for(int j=0,now=0;j<n&&now<=next;j++,now++) {
map[i][j]=sc.nextInt();
}
}
find(0,0,0,0,0,map,n);
System.out.println(max);
sc.close();
}
static void find(int i,int j,int left,int right,int steps,int[][] map,int n) {
if(i==n-1) {
if(Math.abs(left-right)>1)return;
max=Math.max(max, steps+map[i][j]);
return;
}
//向左下角
find(i+1,j,left+1,right,steps+map[i][j],map,n);
//向右下角
find(i+1,j+1,left,right+1,steps+map[i][j],map,n);
}
}
动态规划+贪心版
这个思路相对于不太容易理解一些,我来慢慢梳理。每次赋值的时候就更新dp表,r[i][j] += Math.max(r[i - 1][j - 1], r[i - 1][j]);
的意思就是选择左上角或者右上角较大的累加,先不论左右选择差值的问题,因为根据题目中说的可以到最后再进行判断。最后的判断有两种情况:如果n为奇数,那么只有一种选择的可能,就是选择最后一行的的中间的数,比如下图,n=3,只能选择1那个位置的数;而如果n为偶数,就有两种可能了,只能选择7或者4的位置,选择累加和较大的那个。
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[][] r = new int[n+1][n+1];
for(int i=1; i<=n; ++i) {
for (int j = 1; j <= i; ++j) {
r[i][j] = sc.nextInt();
r[i][j] += Math.max(r[i - 1][j - 1], r[i - 1][j]);
}
}
System.out.println(n%2==1?r[n][n/2+1]:Math.max(r[n][n/2], r[n][n/2+1])); //分奇数和偶数
}
}