第二届传智杯复盘 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();
}
}
如果有人不知道里面的快读快输出,可以参考一下这篇博客哦
第四题暂时没写,写了在补吧,先咕着
推荐阅读