文章目录
- 引言
- 提前
- 图像叠加
- 世界杯积分问题
- 个人实现
- 参考实现
- 直角三角形个数
- 个人实现
- 正式
- 等待时间期望值
- 中位数输出
- 个人实现
- 二次幂和三次幂序列
- 个人实现
- 总结
引言
- 昨天用了牛客网做了一下作业帮的笔试,做的一塌糊涂,但是提醒我要练习使用牛客网的环境进行相关的开发,差不多练了三四个小时,做了两道题。
- 今天晚上七点钟到九点钟是科大讯飞的笔试时间,今天准备上午总结一下以前做的题型,然后的做一套科大讯飞前年的试卷。
- 试卷链接
提前
图像叠加
import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);// deinfe the data to store the imageint m = in.nextInt();int n = in.nextInt();int[][][] img = new int[2][m][n];for(int i = 0;i < 2;i ++){for(int r = 0;r < m;r ++){for(int c = 0;c < n;c ++){img[i][r][c] = in.nextInt();}}}// handle the imgint [][] res = new int[m][n];for(int i = 0;i < m;i ++){for(int j = 0;j < n;j ++){res[i][j] = img[0][i][j] + 2 * img[1][i][j] - 255;if(res[i][j] < 0) res[i][j] = 0;else if(res[i][j] > 255) res[i][j] = 255; System.out.print(res[i][j] + " ");}System.out.println();}}
}
总的来说,这道题还是很简单的!
世界杯积分问题
个人实现
- 这题感觉就是一个正确答案的话,就是能够模拟计算出所有的情况,然后形成一个hash,然后返回大小,并且判定结果是否存在即可!关键在于怎么模拟!
- 不是很懂这个赛制,正常来说肯定是C(5,2),这个感觉得用递归去做,但是我觉得有点别扭,整起来怪怪的!
这里用回溯重实现了一下,是不是太过于繁琐了?
import java.util.Scanner;
import java.util.*;// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {static Set<List<Integer>> set = new HashSet<>();static Pair[] vs = new Pair[10];static class Pair{public int x;public int y;public Pair(int a,int b){x = a;y = b; }}static void dfs(int idx ,List<Integer> score){if(idx == 10) { List<Integer> tempList = new ArrayList<>(score);Collections.sort(tempList);set.add(tempList);}else{// traverse 3 conditions// a win bscore.set(vs[idx].x,score.get(vs[idx].x) + 3);dfs(idx + 1,score);score.set(vs[idx].x,score.get(vs[idx].x) - 3);// a lose bscore.set(vs[idx].y,score.get(vs[idx].y) + 3);dfs(idx + 1,score);score.set(vs[idx].y,score.get(vs[idx].y) - 3);// a and bscore.set(vs[idx].x,score.get(vs[idx].x) + 1);score.set(vs[idx].y,score.get(vs[idx].y) + 1);dfs(idx + 1,score);score.set(vs[idx].x,score.get(vs[idx].x) - 1);score.set(vs[idx].y,score.get(vs[idx].y) - 1);}}public static void main(String[] args) {// define vs[] to store the copmetition seq, score to store the score of each teamList<Integer> score = new ArrayList<>(Arrays.asList(0,0,0,0,0));int idx = 0;for(int i = 0;i < 5;i ++){for(int j = i + 1;j < 5;j ++){vs[idx] = new Pair(i,j);idx ++;}}dfs(0,score);// handle the input Scanner in = new Scanner(System.in);int count = in.nextInt();if(set.size() == count ) System.out.print("yes ");else System.out.print("no ");List<Integer> temp = new ArrayList<>();for(int i = 0;i < 5;i ++){temp.add(in.nextInt());}Collections.sort(temp);if(set.contains(temp)) System.out.println("yes");else System.out.println("no");// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextInt()) { // 注意 while 处理多个 caseint a = in.nextInt();int b = in.nextInt();System.out.println(a + b);}}
}
参考实现
- 同样的方法,但是他写的好像比我简洁!
import java.util.*;public class Main {static Set<List<Integer>> validScores = new HashSet<>();static final int TEAMS = 5;static final int GAMES = 10;public static void main(String[] args) {// 生成所有可能的得分组合generateAllPossibleScores(new int[TEAMS], 0, 0, 0);// 读取输入Scanner scanner = new Scanner(System.in);List<Integer> inputScores = new ArrayList<>();for (int i = 0; i < TEAMS; i++) {inputScores.add(scanner.nextInt());}Collections.sort(inputScores, Collections.reverseOrder());// 判断输入的得分组合是否在所有可能的得分组合中if (validScores.contains(inputScores)) {System.out.println("yes");} else {System.out.println("no");}scanner.close();}// 递归生成所有可能的得分组合static void generateAllPossibleScores(int[] scores, int gameIndex, int teamA, int teamB) {if (gameIndex == GAMES) {List<Integer> sortedScores = new ArrayList<>();for (int score : scores) {sortedScores.add(score);}Collections.sort(sortedScores, Collections.reverseOrder());validScores.add(sortedScores);return;}// 获取当前的比赛队伍组合teamA = gameIndex / (TEAMS - 1);teamB = gameIndex % (TEAMS - 1);if (teamB >= teamA) {teamB++;}// A winsscores[teamA] += 3;generateAllPossibleScores(scores, gameIndex + 1, teamA, teamB);scores[teamA] -= 3;// B winsscores[teamB] += 3;generateAllPossibleScores(scores, gameIndex + 1, teamA, teamB);scores[teamB] -= 3;// Drawscores[teamA] += 1;scores[teamB] += 1;generateAllPossibleScores(scores, gameIndex + 1, teamA, teamB);scores[teamA] -= 1;scores[teamB] -= 1;}
}
但是不是很好读,不是很好理解!
直角三角形个数
个人实现
- 这道题会相对好做一点,准备采用暴力搜索的方式解决,现在是怎么提前计算,才能减少计算量。使用一个二维数组提前保存下来,应该是可以的!
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);// get the dataint count = in.nextInt();int[][] point = new int[count][2];int[][] dist2 = new int[count][count];for(int i = 0;i < count;i ++){point[i][0] = in.nextInt();point[i][1] = in.nextInt();// cal the distance square of the pointsfor(int j = 0;j < i;j ++){dist2[i][j] = (int)Math.pow((point[i][0] - point[j][0]),2) + (int)Math.pow((point[i][1] - point[j][1]),2) ;dist2[j][i] = dist2[i][j];}}// define the set to filter the resultSet<List<Integer>> set = new HashSet<>();for(int a = 0;a < count ;a ++){for(int b = a + 1;b < count ;b ++){for(int c = b + 1;c < count ;c ++){int maxLen = Math.max(Math.max(dist2[a][b],dist2[a][c]),dist2[b][c]);if(2 * maxLen == dist2[a][b] + dist2[a][c] + dist2[b][c]){set.add(Arrays.asList(a,b,c));}}}}System.out.println(set.size());}
}
这里直接暴力通过了,还是比较意外的,感觉应该有什么特殊的数学关系可以调用的!
正式
等待时间期望值
- 这个太简单了,就不写了!
中位数输出
- 给你n个整数,每一个数字是0到10的九次方,然后你找到它的中位数进行输出
- 如果序列是偶数,有以下两种情况处理
- 两数相等,随便输出一个
- 两数不等,输出较小的一个
- 如果的序列是奇数,直接输出中间值。
- 如果序列是偶数,有以下两种情况处理
- 持续输出,直到输出整个序列!
输入样例
- 5
- 1 2 3 4 5
输出样例
- 3 2 4 1 6
个人实现
- 这里使用对顶堆实现,不过我花了很多时间,不应该是这样的!
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);int count = in.nextInt();PriorityQueue<Integer> front = new PriorityQueue<>(Comparator.reverseOrder());PriorityQueue<Integer> back = new PriorityQueue<>();for(int i = 0;i < count ;i ++) back.add(in.nextInt());while(!front.isEmpty() || !back.isEmpty()){while(front.size() < back.size()){front.add(back.poll());}if(front.size() == back.size()){if(front.peek() < back.peek()){System.out.print(front.poll() + " ");}else {System.out.print(back.poll() + " ");}}else{System.out.print( front.poll()+ " ");}}}
}
二次幂和三次幂序列
- 先给一个数字n,n = 3 x 0 ∗ 2 y 0 3^{x_0}* 2^{y_0} 3x0∗2y0 + 3 x 1 ∗ 2 y 1 3^{x_1}* 2^{y_ 1} 3x1∗2y1 + 3 x 2 ∗ 2 y 2 3^{x_2}* 2^{y_2} 3x2∗2y2,然后将上述每一个子项按照从小到大进行排序,输出对应序列为{ 3 x 0 ∗ 2 y 0 3^{x_0}* 2^{y_0} 3x0∗2y0 , 3 x 1 ∗ 2 y 1 3^{x_1}* 2^{y_ 1} 3x1∗2y1 , 3 x 2 ∗ 2 y 2 3^{x_2}* 2^{y_2} 3x2∗2y2},不要求找一个最短的,只要能够输出就行。不如说10 = 3 0 ∗ 2 3 3^{0}* 2^{3} 30∗23 + 3 0 ∗ 2 1 3^{0}* 2^{1} 30∗21,输出的序列是{2,8},只要输出一个就行了!
- n的数字范围是1到10的9次方。
个人实现
- 这道题当时没有写完,但是有了基本的思路,使用最基本的回溯实现。
- 我很懊恼呀,明明能够写出来的,我一开始误认为是零一背包,然后整了半天,发现还是得回溯,还是编程得速度不够快,当时没有想清楚,不应该!属实不应该!就是应该多练习一下!
import java.util.Scanner;
import java.util.*;// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {static boolean dfs(int num,Map<Integer,Boolean> map,List<Integer> res){if(num == 0){Collections.sort(res,Collections.reverseOrder());for(int i = 0; i < res.size(); i++) {System.out.print(res.get(i) + " ");}System.out.println();return true;}for(int x:map.keySet()){if(map.get(x) == true && x <= num){res.add(x);map.put(x,false);if(dfs(num - x,map,res)) return true;res.remove(res.size() - 1);map.put(x,true);}}return false;}public static void main(String[] args) {Scanner in = new Scanner(System.in);int num = in.nextInt();// define two arrays to store the exp of 2 and 3int[] exp2 = new int[31];for(int i = 0; i < 31; i++) {exp2[i] = (int)Math.pow(2, i);}int[] exp3 = new int[19];for(int i = 0; i < 18; i++) {exp3[i] = (int)Math.pow(3, i);}// define the map to store the numMap<Integer,Boolean> map = new HashMap<>();for(int i = 0; i < 31; i++) {for(int j = 0; j < 18; j++) {if((long)exp2[i] * (long)exp3[j] <= Integer.MAX_VALUE)map.put(exp2[i] * exp3[j], true);}}// find the resList<Integer> res = new ArrayList<>();dfs(num,map,res);}
}
捶胸顿足,难受,差不多都做出来了,但是时间没有安排好,还有就是写的太慢了!是什么让你写的那么慢?
- 不确定使用哪种数据结构,然后来回切换两种方法==》对于回溯还不够熟悉!
- 对于相关函数还不够熟悉!
总结
-
练习题做了蛮长时间的,不过好在都做出来了,还是得加快编码的速度!加油!
-
今天做了,还是蛮失望的,没想到有那么多选择题,考察面很广,实际上用来做算法题的时间并不多,最终效果做的一般!
- 第一题,五分钟写完了,但是只能通过27%的样例,花了半个小时改,最终没什么效果
- 第二题,半个小时写完,但是通过百分之八十的样例,后来花时间重写了对顶堆,然后的通过了所有样例,花的时间有点久!不应该!
- 第三题,没写出来,应该是使用回溯做出来的!但是没写出来,时间太短了!现在五分钟就写出来了!但凡平和的心态再来五分钟,我就能写完!肯定能够写完!
-
暴露出两个问题
- 题目写少了,对于很多Java的方法还不熟悉,比如说isEmpty不是Empty还在这整半天
- 然后回溯类的题型刷少了,不应该,后续把回溯全部刷完!
- 回溯和动态规划就是可以相互转换的!