第二届传智杯复盘 Java(自闭)代码

诶,过去一天了,昨天真的让我知道了不能小看任何一道题(差点就爆零了!!)。
这里来复盘一下自己比赛的时候出现的错误

 (谁说传智杯简单的,我过去就是一脚

软件工程实习:

题目描述:
某大学的《软件工程》必修课分为理论和实践部分。理论部分由该校教授完成授课;而实践部分是由第三方的公司主导,需要同学们在五周时间内自学 HTML、css、JavaScript、vue、Python、django 等技术,并组队完成一个真实的互联网商业应用。
参与这个课程的有 n(0≤n≤1000) 个学生,分成了不超过 26 个队伍,每个队伍用 A 到 Z 来表示。每个队伍都会完成一个项目,并以队伍为单位,给所有队伍(包括自己队伍)打分,范围是 0 到 100 的整数。
为了平息学生对这门课产生的出多问题的不满(比如工作量太大、时间过于紧张、考核方式不公平等),老师决定使用一种“看起来”很公平的方式来决定每组队伍的项目得分:
对于某个队伍,首先计算所有队伍(包括自己)给这个队伍评分的平均值,然后剔除掉和这个平均值差别超过 15 分的评分(保证不会出现所有的评分全部被剔除的情况),最后再对剩余的评分求平均值,四舍五入取整后作为这个队伍的项目得分。
对于每一个同学,我们已经得知他们的队伍代号和理论成绩(也是 0 到 100 分的整数)。这位同学的最后得分就是 60% 的理论成绩加上 40% 的所在队伍的项目得分,然后四舍五入取整。
现在老师想知道所有同学的分数排行。请按最后得分从高到低的顺序,输出每位同学的得分和他所在的队伍。
输入格式:
在这里插入图片描述

输出格式:
输出 n 行表示答案,得分高的同学优先输出,得分相同时队伍编号较小的同学优先输出。对于每一行,先输出这位同学成绩,然后输出代表他的队伍编号的大写英文字母。

易错点:
(1)首先拿到这个题,这么长的题目,就让我烦躁得很,也是因为自己第一次参加这种正式性的比赛,诶,有点紧张吧还是,首先我们必须得把题目认认真真地读完。
(2)第一个易错点,当我们剔除掉平均分后我们必须得四舍五入一下,然后当我们计算出来每个同学的成绩时,我们还是必须得四舍五入一下!
(3)第二个易错点,相信大家也看见了,我上面标注出来了,得分相同的时候队伍编号小的优先输出啊!!!!(这里我比赛的时候无限WA,眼睛瞎了)
(4)第三个易错点,在每个队伍打分的时候,他不是说每一行就是这一个队伍的得分啊!他是说每一行是每一个队伍给别的队伍打的分!!
例如:
70 90 100
95 88 85
30 47 100
A的得分是:70 95 30
B的得分是:90 88 47
依次类推,而不是说什么A的得分是 70 90 100 !! (害 - - 给自己长个记性吧,这个题WA了很多发,最后心态都炸了,比赛可想而知)
最后贴出代码:

package 传智杯第二届;
import java.util.*;
public class Test1 {
	static int n,k;
	static int a[][] = new int[30][30]; // 每个队伍互相打的分数
	static double avg[] = new double[30]; // 每个队伍平均分
	static double sum[] = new double[30]; // 每个队伍分数总和
	static int cnt[] = new int[30]; // 每个队伍现在有效得分次数
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		k = sc.nextInt();
		student stu[] = new student[n];
		for(int i = 0;i < n;i++){
			stu[i] = new student();
			stu[i].t = sc.nextInt();
			stu[i].no = sc.next().charAt(0);
		}
		for(int i = 0;i < k;i++){
			for(int j = 0;j < k;j++){
				a[j][i] = sc.nextInt();
				sum[j] += a[j][i]; // 每个队伍的成绩和
			}
		}
		for(int i = 0;i < k;i++)
			avg[i] = sum[i]/(double)k;
		Arrays.fill(cnt,k);
		for(int i = 0;i < k;i++)
			for(int j = 0;j < k;j++){
				if(Math.abs(avg[i]-(double)a[i][j]) > 15){
					sum[i] -= a[i][j];
					cnt[i]--;
				}
			}
		for(int i = 0;i < k;i++)
			avg[i] = (int)(sum[i]/(double)cnt[i]+0.5);
		for(int i = 0;i < n;i++)
			stu[i].t = (int)(stu[i].t*0.6+avg[stu[i].no-'A']*0.4+0.5);
		Arrays.sort(stu);
		for(int i = 0;i < n;i++)
			System.out.println(stu[i].t+" "+stu[i].no);
		sc.close();
	}
}
class student implements Comparable{
	int t;
	char no;
	public int compareTo(Object b){
		student a = (student)b;
		if(this.t < a.t)
			return 1;
		else if(this.t == a.t){
			if(this.no > a.no)
				return 1;
			else
				return -1;
		}
		else return -1;
	}
}

程序员节发橙子

题目描述:
在这里插入图片描述
输入格式:
在这里插入图片描述
输出格式:
输出答案,也就是需要最少准备多少个橙子。

错误思想:
这个题我的想法居然是找出最小成绩的那个同学,然后以他为标准,分别向两边去扩散,殊不知这个是完全错误的。
当然对于样例是没一点毛病
样例:
5
3 4 5 4 3
输出 9 // 1 2 3 2 1 没一点毛病
当时如果是 6 1 9 7 6
这种思想的话给的橘子数为 : 2 1 2 1 0
居然出现0了!

正确的思想是:
(1)我们先假设每个人先发一个橘子,因为每个人至少要收到一个橘子
(2)从左到右扫描一遍,然后如果右边的成绩比左边的大,不用说这个人分的橘子数肯定是左边那个人+1,我们不要在这个时候判断右边比左边小的,因为这个可能会导致出现负数。
(3)最后从右向左扫描一遍,如果左边比右边大的话,a[i-1] = max(a[i-1],a[i]+1)相等的话:
a[i-1] = max(a[i-1],a[i]) 相信也挺好理解的

代码:

package 传智杯第二届;
import java.io.*;
public class Test2 {
	static int n;
	static int a[] = new int[1000010];
	static int num[] = new int[1000010];
	public static void main(String[] args) throws IOException{
		StreamTokenizer re = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
		PrintWriter pr = new PrintWriter(new OutputStreamWriter(System.out));
		re.nextToken(); n = (int)re.nval;
		long ans = 0;
		for(int i = 1; i <= n;i++){
			re.nextToken();
			a[i] = (int)re.nval;
		}
		for(int i = 1;i < n;i++){
			if(a[i] < a[i+1])
				num[i+1] = num[i]+1;
			else if(a[i] == a[i+1])
				num[i+1] = num[i];
		}
		for(int i = n;i > 1;i--){
			if(a[i] < a[i-1])
				num[i-1] = Math.max(num[i-1],num[i]+1);
			else if(a[i] == a[i-1])
				num[i-1] = Math.max(num[i-1],num[i]);
		}
		for(int i = 1;i <= n;i++)
			ans += num[i];
		pr.println(ans+n);
		pr.flush();
	}
}

众数出现的次数

题目描述:
在这里插入图片描述
输入格式:
在这里插入图片描述
输出格式:
在这里插入图片描述
首先这个题我感觉可能是这套题最没有坑点的题了吧,题意简单明了,但是这个题还是考察了对于Map的使用吧。。 听说有大佬没用Map , 害 不过我这种菜鸡也只能这样了
分析题目:
(1)首先这个题有1e6的同学 每个同学都有可能出的数字都有2个,我们如果把这些存到这个数组中好了,写到这里我知道为什么可以不用Map了。。我是傻逼 开个2*1e6的数组排序一下就可以记录了吧。
(2)因为我当时排序的时候我想到的是桶排,看到数字1e9我以为排序不行,诶,dbqwtcl。
(3)不过这个题我们还是可以用map的!我们可以把每个数和每个数出现的次数以键值对的形式存进map中,然后我们需要的答案就是value最大值的那个数字对应的键

代码:

package 传智杯第二届;
import java.io.*;
import java.util.*;
import java.util.Map.Entry;
public class Test3 {
	static int n;
	static int a[] = new int[1000010];
	static int b[] = new int[1000010];
	static HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
	public static void main(String[] args) throws IOException{
		StreamTokenizer re = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
		PrintWriter pr = new PrintWriter(new OutputStreamWriter(System.out));
		re.nextToken(); n = (int)re.nval;
		for(int i = 1;i <= n;i++){
			re.nextToken();
			a[i]  = (int)re.nval;
			re.nextToken();
			b[i] = (int)re.nval;
			b[i] = a[i]^b[i];
			map.put(a[i],0);
			map.put(b[i],0);
		}
		for(int i = 1;i <= n;i++){
			if(a[i] != b[i]){
				map.put(a[i],map.get(a[i])+1);
				map.put(b[i],map.get(b[i])+1);
			}
			else
				map.put(a[i],map.get(a[i])+1);
		}
		int k = 0;
		long ans = 0;
		for(Entry<Integer,Integer> entry : map.entrySet()){ // 这里可能比较关键 使用Entry可以很好很快速的返回每一个键值对的键与值
			if(entry.getValue() > ans){
				ans = entry.getValue();
				k = entry.getKey();
			}
			else if(entry.getValue() == ans && entry.getKey() < k)
				k = entry.getKey();
		}
		pr.println(k);
		pr.flush();
	}
}

如果有人不知道里面的快读快输出,可以参考一下这篇博客哦
第四题暂时没写,写了在补吧,先咕着

发布了32 篇原创文章 · 获赞 5 · 访问量 862

猜你喜欢

转载自blog.csdn.net/shizhuba/article/details/105465194