当前位置:   article > 正文

【2023华为od机考】算法题答案记录100分题_华为前端od算法题

华为前端od算法题

准备od机考中, c++答案和java都有

标括号(博客)代表是题目链接里给的答案, 大部分是自己写的, 比较喜欢打上注释, 帮助理解

我觉得c++还是简洁点, 不过有的题目就是为了考java的集合用法, 就用java更好

题目链接

华为OD机试真题2023(JAVA&JS)_华为机试真题_若博豆的博客-CSDN博客

1 猜字谜

c++代码(我写的)

  1. #include <iostream>
  2. #include <algorithm>
  3. using namespace std;
  4. const int N = 20010;
  5. string aa[N], bb[N];
  6. int main()
  7. {
  8. string a;//谜面
  9. string b;//谜底 在谜底中找谜面里的错误词
  10. getline(cin, a);
  11. getline(cin, b);
  12. string res;//每个单词
  13. int count = 0;
  14. for(int i = 0; i < a.length(); i ++ )
  15. {
  16. if(a[i] == ',')
  17. {
  18. aa[count ++ ] = res;
  19. res = "";
  20. }
  21. else res += a[i];
  22. }
  23. aa[count] = res;//最后一个res也存进去 count不用加了
  24. int len_aa = count + 1;
  25. res = "";
  26. count = 0;
  27. for(int i = 0; i < b.length(); i ++ )
  28. {
  29. if(b[i] == ',')
  30. {
  31. bb[count ++ ] = res;
  32. res = "";
  33. }
  34. else res += b[i];
  35. }
  36. bb[count] = res;//最后一个res也存进去 count不用加了
  37. int len_bb = count + 1;
  38. bool flag = false;//是否找到
  39. bool comma = false;//是否有逗号
  40. //然后两个字符串数组就是 aa 和 bb, 长度分别是len_aa, len_bb
  41. for(int i = 0; i < len_aa; i ++ ) {//循环aa字符串数组,
  42. string str = aa[i];
  43. sort(str.begin(), str.end());
  44. str.erase(unique(str.begin(), str.end()), str.end()); //去掉重复元素
  45. for(int j = 0; j < len_bb; j ++ ) {
  46. string str2 = bb[j];
  47. sort(str2.begin(), str2.end());
  48. str2.erase(unique(str2.begin(), str2.end()), str2.end());
  49. if(str2 == str) {
  50. if(comma) cout << ',';
  51. cout << bb[j];
  52. flag = true;
  53. comma = true;
  54. break;
  55. }
  56. }
  57. if(flag == false) cout << "not found" << endl;
  58. flag = false;
  59. }
  60. return 0;
  61. }

java代码(博客里的):

  1. import java.util.*;
  2. public class Main {
  3. public static void main(String[] args) {
  4. Scanner in = new Scanner(System.in);
  5. String[] question=in.nextLine().split(",");
  6. String[] answer=in.nextLine().split(",");
  7. List<String> resList=new ArrayList<>();
  8. for(int i=0;i<question.length;i++){
  9. String q=question[i];
  10. boolean isFound=false;
  11. for(int j=0;j<answer.length;j++){
  12. String a=answer[j];
  13. if(change(q,a)){
  14. resList.add(a);
  15. isFound=true;
  16. }else if(dist(q,a)){
  17. resList.add(a);
  18. isFound=true;
  19. }
  20. }
  21. if(!isFound){
  22. resList.add("not found");
  23. }
  24. }
  25. String res= "";
  26. for(int i=0;i<resList.size();i++){
  27. res+=resList.get(i)+",";
  28. }
  29. System.out.println(res.substring(0,res.length()-1));
  30. }
  31. public static boolean dist(String question,String answer){
  32. List<Character> qList=new ArrayList<>();
  33. for(int i=0;i<question.length();i++){
  34. char c=question.charAt(i);
  35. if(!qList.contains(c)){
  36. qList.add(c);
  37. }
  38. }
  39. List<Character> aList=new ArrayList<>();
  40. for(int i=0;i<answer.length();i++){
  41. char c=answer.charAt(i);
  42. if(!aList.contains(c)){
  43. aList.add(c);
  44. }
  45. }
  46. if(qList.equals(aList)){
  47. return true;
  48. }
  49. return false;
  50. }
  51. public static boolean change(String question,String answer){
  52. String[] qStr=question.split("");
  53. Arrays.sort(qStr);
  54. String[] aStr=answer.split("");
  55. Arrays.sort(aStr);
  56. if(Arrays.equals(qStr,aStr)){
  57. return true;
  58. }
  59. return false;
  60. }
  61. }

2 木板

题目链接: 

【满分】【华为OD机试真题2023 JAVA&JS】木板_若博豆的博客-CSDN博客

java代码(博客里的):

  1. public class Main{
  2. public static void main(String[] args) {
  3. Scanner sc = new Scanner(System.in);
  4. int n = sc.nextInt();
  5. int m = sc.nextInt();
  6. int[] nums = new int[n];
  7. for(int i=0; i<n; i++){
  8. nums[i] = sc.nextInt();
  9. }
  10. Arrays.sort(nums);
  11. while (m>0){
  12. m--; //木材一段一段的截
  13. for(int i=1; i<n; i++){
  14. if(nums[i] > nums[i-1]){
  15. nums[i-1] ++; //碰到比后面的短的就加一截
  16. break;
  17. }
  18. if(i == n-1){
  19. nums[i] ++; //所有木材一样长则在最后一根加一截
  20. }
  21. }
  22. }
  23. System.out.println(nums[0]);
  24. }
  25. }

c++代码:

  1. #include <iostream>
  2. #include <algorithm>
  3. using namespace std;
  4. const int N = 100010;
  5. int n, m;
  6. int a[N];
  7. int main()
  8. {
  9. scanf("%d%d", &n, &m);
  10. int min = 0;
  11. for(int i = 0; i < n; i ++ )
  12. scanf("%d", &a[i]);
  13. sort(a , a + n);//从小到大排序
  14. while(m -- ) {
  15. for(int i = 1; i < n; i ++ ) {
  16. if(a[i] > a[i - 1])//如果比前一个长, 前一个+1
  17. {
  18. a[i - 1] ++ ;//
  19. break;
  20. }//否则 不加
  21. if(i == n - 1)//遍历到尾巴了, 就最后一节+1
  22. {
  23. a[i] ++ ;
  24. }
  25. }
  26. }
  27. cout << a[0] << endl;
  28. return 0;
  29. }

3 查找重复代码

题目链接:

java(博客里的)

  1. import java.util.Scanner;
  2. public class Main {
  3. public static void main(String[] args) {
  4. Scanner sc = new Scanner(System.in);
  5. String str1 = sc.nextLine();
  6. String str2 = sc.nextLine();
  7. String result = "";
  8. int start = 0;
  9. int end = 1;
  10. while(end <= str2.length()){
  11. String subStr = str2.substring(start,end);
  12. if (str1.contains(subStr)){
  13. result = subStr;
  14. }else {
  15. start++;
  16. }
  17. end++;
  18. }
  19. System.out.println(result);
  20. }
  21. }

c++代码:

  1. #include <iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. string a;//0-200 暴力枚举
  6. string b;
  7. getline(cin, a);
  8. getline(cin, b);
  9. int len1 = a.length();
  10. int len2 = b.length();
  11. if(len1 > len2) swap(a, b);//让a是短的
  12. string res = "";
  13. //双指针 [i,j] 判断 n * n = 10000
  14. for(int j = len1 - 1; j > 0; j -- )
  15. {
  16. for(int i = 0; i < j; i ++ )
  17. {
  18. string temp = a.substr(i, j - i + 1);
  19. if(b.find(temp) != -1) {
  20. if(temp.length() > res.length())
  21. res = temp;
  22. }
  23. }
  24. }
  25. cout << res << endl;
  26. return 0;
  27. }

5 单词倒序

java代码(博客里的)

  1. import java.util.Scanner;
  2. public class Main {
  3. public static void main(String[] args) {
  4. Scanner scanner = new Scanner(System.in);
  5. String str = scanner.nextLine();
  6. String result = "";
  7. int start = 0;
  8. for (int i = 0; i< str.length(); i++) {
  9. char a = str.charAt(i);
  10. if (a==' ' || a=='?' || a=='.' || a==',') {
  11. if (i > start) {
  12. StringBuilder word = new StringBuilder(str.substring(start, i));
  13. result = result + word.reverse() + a;
  14. } else {
  15. result = result + a;
  16. }
  17. start = i + 1;
  18. } else if (i == str.length() -1) {
  19. StringBuilder word = new StringBuilder(str.substring(start, i + 1));
  20. result = result + word.reverse();
  21. }
  22. }
  23. System.out.println(result);
  24. }
  25. }

c++代码:

  1. #include <iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. string a[100];
  6. int i = 0;
  7. while(cin >> a[i]) i ++;
  8. for(int j = 0; j < i; j ++ )
  9. {
  10. //取出字符串数组中的每个字符串a[i]
  11. string str = a[j];
  12. char temp = '\0';
  13. for(int k = str.length() - 1; k >= 0; k -- )
  14. {
  15. //反转后将字符串中的每个字符输出
  16. //如果是标点, 先不输出
  17. if(str[k] == ',' || str[k] == '.' || str[k] == '!') {
  18. temp = str[k];
  19. }
  20. else cout << str[k];
  21. }
  22. if(temp != '\0') cout << temp;
  23. cout << ' ';
  24. temp = '\0';
  25. }
  26. cout << endl;
  27. return 0;
  28. }

6 打印文件

java代码(博客里的)

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. import java.util.Scanner;
  4. public class Main {
  5. public static void main(String[] args) {
  6. List<List<File>> m = new ArrayList<>();
  7. for (int i = 0; i < 5; i++) {
  8. m.add(new ArrayList<>());
  9. }
  10. Scanner in = new Scanner(System.in);
  11. int n = in.nextInt();
  12. int flag = 0;
  13. for (int i = 0; i <= n; i++) {
  14. String s = in.nextLine();
  15. String[] s1 = s.split(" ");
  16. String type = s1[0];
  17. if ("IN".equals(type)) {
  18. int p = Integer.parseInt(s1[1]);
  19. int num = Integer.parseInt(s1[2]);
  20. flag++;
  21. File file = new File(flag, num);
  22. List<File> files = m.get(p - 1);
  23. files.add(file);
  24. } else if ("OUT".equals(type)) {
  25. int p = Integer.parseInt(s1[1]);
  26. List<File> files = m.get(p - 1);
  27. if (files != null && files.size() > 0) {
  28. files.sort((a, b) -> {
  29. return b.getWeight() - a.getWeight();
  30. });
  31. File file = files.get(0);
  32. System.out.println(file.getIndex());
  33. files.remove(0);
  34. } else {
  35. System.out.println("NULL");
  36. }
  37. }
  38. }
  39. }
  40. }
  41. class File {
  42. private int index;
  43. private int weight;
  44. public File(int index, int weight) {
  45. this.index = index;
  46. this.weight = weight;
  47. }
  48. public int getIndex() {
  49. return index;
  50. }
  51. public void setIndex(int index) {
  52. this.index = index;
  53. }
  54. public int getWeight() {
  55. return weight;
  56. }
  57. public void setWeight(int weight) {
  58. this.weight = weight;
  59. }
  60. }

c++代码: 

  1. #include <iostream>
  2. #include <algorithm>
  3. #define x first
  4. #define y second
  5. using namespace std;
  6. const int N = 1010;
  7. typedef pair<int, pair<int, int>> PII;
  8. int m;
  9. vector<PII> alls;
  10. int main()
  11. {
  12. scanf("%d", &m);
  13. int count = 1;//文件的编号
  14. while(m -- ) {
  15. string op;
  16. cin >> op;
  17. int p, n;
  18. bool flag = false;
  19. if(op == "IN")
  20. {
  21. scanf("%d%d", &p, &n);//打印机编号p, 优先级n
  22. alls.push_back({n, {count, p}});
  23. count ++ ;
  24. //sort(alls.rbegin(), alls.rend());//按照n排序
  25. sort(alls.rbegin(), alls.rend(), [](const PII &a, const PII &b){
  26. return a.x < b.x; // 先按照优先级n降序, 再按照插入顺序count升序
  27. });
  28. // for(auto e : alls)
  29. // {
  30. // cout << e.x << ' '<< e.y.x << ' ' << e.y.y << endl;
  31. // } cout << endl;
  32. }
  33. else if(op == "OUT")
  34. {
  35. scanf("%d", &p);
  36. int len = alls.size();
  37. //遍历输出结果
  38. for(int i = 0; i < len; i ++ )
  39. {
  40. //如果有结果 输出结果, 在数组中删除该数 flag=true, 退出循环
  41. if(alls[i].y.y == p)
  42. {
  43. cout << alls[i].y.x << endl;
  44. auto iter = alls.erase(alls.begin() + i);//删除元素
  45. flag = true;
  46. break;
  47. }
  48. }
  49. //如果遍历完都没有结果, flag还是false 输出NULL
  50. if(flag == false) cout << "NULL" << endl;
  51. flag = false;
  52. }
  53. }
  54. return 0;
  55. }

7 对称字符串

c++代码, 不过这个回溯会爆内存 报memory limit exceeded 或者 time limit exceeded

  1. #include <iostream>
  2. using namespace std;
  3. const int N = 100010;
  4. int t, n, k;
  5. string solve(int x) {//每次就是把前一个的字符串取反 + 原字符串
  6. if(x == 1) return "R";//1输出R
  7. string str = solve(x - 1);
  8. string res = "";
  9. for(int i = 0; i < str.length(); i ++ ) {
  10. if(str[i] == 'R') res += 'B';
  11. else if(str[i] == 'B') res += 'R';
  12. }
  13. return res + str; //翻转结果 + 原字符串
  14. }
  15. int main()
  16. {
  17. scanf("%d", &t);
  18. while(t -- ) {
  19. scanf("%d%d", &n, &k);
  20. string ans = solve(n);//只能在25以内, 否则memory limit exceeded
  21. if(ans[k] == 'R') cout << "red" << endl;
  22. else cout << "blue" << endl;
  23. }
  24. return 0;
  25. }

 c++ 找规律写法: 这个是扒的博客java解法

  1. #include <iostream>
  2. #include <cmath>
  3. #include <algorithm>
  4. typedef long long ll;
  5. using namespace std;
  6. int t, n, k;//n是第几个字符串, k是字符的位置
  7. int solve(ll len, ll k, int rev) //len是字符串的长度, k是位置, rev是翻转次数
  8. {
  9. if(len == 1) return rev;//回溯到最底层 就返回现在的rev就是翻转的次数
  10. ll half = len / 2;//长度的一半
  11. if(k < half) { //k在前半部分, 是反转后的部分
  12. rev ++ ;//翻转次数++
  13. return solve(half, k, rev);
  14. } else {//后半部分
  15. return solve(half, k - half, rev);
  16. }
  17. }
  18. int main()
  19. {
  20. scanf("%d", &t);
  21. while(t -- ) {
  22. scanf("%d%d", &n, &k);
  23. //长度
  24. ll len = (ll)pow(2, n - 1);
  25. //cout << len << endl;
  26. int ans = solve(len, k, 0);//传入长度, 位置, 求该位置的翻转次数
  27. //原字符是R 翻转偶数次就是R 翻转奇数次就是B
  28. if(ans % 2) cout << "blue" << endl;//奇数次
  29. else cout << "red" << endl;//偶数次
  30. }
  31. return 0;
  32. }

java代码(博客)

  1. public class Main{
  2. public static void main(String[] args) {
  3. Scanner sc = new Scanner(System.in);
  4. int T = sc.nextInt();
  5. for(int i=0; i<T; i++){
  6. int n = sc.nextInt();
  7. long k = sc.nextLong();
  8. long charNum = (long) Math.pow(2, n - 1); //第n行的总字符个数
  9. int re = doProcess(charNum, k, 0);
  10. if (re % 2 == 0) {
  11. System.out.println("red"); //翻转次数为2的倍数
  12. } else {
  13. System.out.println("blue");
  14. }
  15. }
  16. }
  17. /**
  18. * 翻转次数
  19. * @param count 总字符的个数
  20. * @param cur 字符的索引
  21. * @param reverse 翻转次数
  22. * @return
  23. */
  24. public static int doProcess(long count, long cur, int reverse){
  25. if (count == 1) {
  26. return reverse;
  27. }
  28. long half = count / 2;
  29. if (cur < half) { //小于半数说明是经过翻转的部分
  30. reverse ++;
  31. return doProcess(half, cur, reverse);
  32. } else {
  33. return doProcess(half, cur - half, reverse);
  34. }
  35. }
  36. }

8 分界线

爷的c++代码, 纯打暴力

  1. #include <iostream>
  2. #include <algorithm>
  3. using namespace std;
  4. const int N = 110;
  5. string aa[N], bb[N];
  6. int main()
  7. {
  8. string a;//报纸内容
  9. string b;//是否可以拼成的 匿名信
  10. getline(cin, a);
  11. getline(cin, b);
  12. string res = "";
  13. int j = 0;
  14. for(int i = 0; i < a.length(); i ++ ) //100 * 104 = 100400
  15. {
  16. if(a[i] == ' ') {
  17. aa[j ++ ] = res;
  18. res = "";
  19. } else res += a[i];
  20. } aa[j ++ ] = res;
  21. //存进去了aa[N] 报文的字符串数组
  22. int len_a = j;
  23. res = "";
  24. j = 0;
  25. for(int i = 0; i < b.length(); i ++ ) //100400
  26. {
  27. if(b[i] == ' ') {
  28. bb[j ++ ] = res;
  29. res = "";
  30. } else res += b[i];
  31. } bb[j ++ ] = res;
  32. //存进去了bb[N] 报文的字符串数组
  33. int len_b = j;
  34. int count = 0;
  35. for(int i = 0; i < len_b; i ++ ) {//枚举每个匿名信单词
  36. string ano = bb[i];
  37. sort(ano.begin(), ano.end());
  38. for(int j = 0; j < len_a; j ++ ) {//枚举原报文遍历单词
  39. string news = aa[j];
  40. sort(news.begin(), news.end());
  41. if(ano == news) {
  42. count ++ ;
  43. break;//结束报文的遍历
  44. }
  45. }
  46. }
  47. if(count == len_b) cout << "true" << endl;
  48. else cout << "false" << endl;
  49. return 0;
  50. }

java(博客里的)

  1. import java.util.Arrays;
  2. import java.util.Scanner;
  3. public class Main {
  4. public static void main(String[] args) {
  5. Scanner sc = new Scanner(System.in);
  6. String newsapper = sc.nextLine();
  7. String anonymousLetter = sc.nextLine();
  8. String[] newsapperArr = newsapper.split(" ");
  9. String[] anonymousLetterArr = anonymousLetter.split(" ");
  10. for (int i = 0; i < anonymousLetterArr.length; i++) {
  11. String ii = anonymousLetterArr[i];
  12. char[] ic = ii.toCharArray();
  13. Arrays.sort(ic);
  14. boolean flag = false;
  15. for (int j = 0; j < newsapperArr.length; j++) {
  16. String jj = newsapperArr[j];
  17. char[] jc = jj.toCharArray();
  18. Arrays.sort(jc);
  19. if (Arrays.equals(ic, jc)){
  20. flag = true;
  21. break;
  22. }
  23. }
  24. if (!flag){
  25. System.out.println(false);
  26. System.exit(0);
  27. }
  28. }
  29. System.out.println(true);
  30. }
  31. }

9 关联端口组合并

string数组转成int数组的方法: 

String数组转int数组_躺平的菜鸟啊的博客-CSDN博客

不需要像c++那样遍历了哈哈哈,  java也不错嘛

java代码(博客里的思路) 我打了备注, 改动了一点:

  1. import java.util.*;
  2. public class Main{
  3. public static void main(String[] args){
  4. Scanner myScanner = new Scanner(System.in);
  5. //二维数组, 外层用list保存, 内层用set集合保存, set集合有去重和排序的功能,
  6. //每输入一个组合, 对list进行遍历, 找出其中有两个并集的集合进行合并
  7. int m = myScanner.nextInt();
  8. if(m > 10) System.out.println("[[]]");
  9. else {
  10. List<Set<Integer>> list = new ArrayList<>();
  11. //myScanner.nextLine();//读取行
  12. //循环
  13. for(int i = 0; i < m; i ++ ) {
  14. String[] strings = myScanner.nextLine().split(",");//读取行 分成zi字符串数组strings
  15. int[] nums = Arrays.stream(strings).mapToInt(Integer::parseInt).toArray();//转换成字符串数组nums
  16. Set<Integer> set = new TreeSet<>();
  17. if(nums.length == 1 ) {//只有一个元素, 直接添加
  18. set.add(nums[0]);
  19. list.add(set);//加入list
  20. } else {
  21. for(int num : nums) {
  22. set.add(num);//数字加到set集合中
  23. }
  24. list.add(set);//这个新的set加到list, 默认加到最后
  25. merge(set, list, list.size() - 1 );//看是否需要合并set和list内的set
  26. }
  27. }
  28. System.out.println(list);//输出结果
  29. }
  30. }
  31. public static void merge(Set<Integer> set, List<Set<Integer>> list, int index) {
  32. for(int i = 0; i < list.size(); i ++ ) {//遍历list中的每个set
  33. if(i == index) continue;//如果是相同 就不继续了
  34. Set<Integer> setIdx = list.get(i);//当前索引的set集合
  35. Set<Integer> setTemp = new TreeSet<>();
  36. setTemp.addAll(set);//临时集合 保存交集
  37. setTemp.retainAll(setIdx);//待判断的set和当前的setIdx的交集, 返回交集
  38. if(setTemp.size() >= 2) {//当交集>=2 则需要合并
  39. set.addAll(setIdx); //把新传入的set与setIdx合并
  40. list.remove(i);//两个都移除后
  41. list.remove(index);
  42. int st = i < index ? i : index;//存靠前的下标
  43. list.add(st, set);//加上并集set 在st位置
  44. merge(set, list, st);//新建的组合再进行判断合并, 因为合并之后
  45. }
  46. }
  47. }
  48. }

10 货币单位换算

c++代码, 按照博客思路写的

  1. #include <iostream>
  2. #include <cmath>
  3. #include <algorithm>
  4. using namespace std;
  5. int n;
  6. double solve(string str, char c) {
  7. double res;
  8. for(int i = 0; i < str.length(); i ++ ) {
  9. res *= 10;
  10. res += str[i] - '0';
  11. }
  12. if(c == 'C') res *= 100;
  13. else if(c == 'J') res *= (double) 10000 / 1825;
  14. else if(c == 'H') res *= (double) 10000 / 123;
  15. else if(c == 'E') res *= (double) 10000 / 14;
  16. else if(c == 'G') res *= (double) 10000 / 12;
  17. else if(c == 'f') res *= 1;
  18. else if(c == 's') res *= (double) 100 / 1825;
  19. else if(c == 'c') res *= (double) 100 / 123;
  20. else if(c == 'e') res *= (double) 100 / 14;
  21. else if(c == 'p') res *= (double) 100 / 12;
  22. return res;
  23. }
  24. int main(){
  25. scanf("%d", &n);
  26. double res = 0;
  27. while(n -- ) {
  28. string str;
  29. cin >> str;
  30. string tmp;
  31. for(int i = 0; i < str.length(); i ++ ) {
  32. char c = str[i];
  33. if(c >= '0' && c <= '9') tmp += str[i];
  34. else {
  35. res += solve(tmp, c);
  36. i += 2;
  37. if(c == 'c') i += 2;
  38. else if(c == 'e') i += 8;
  39. else if(c == 'p') i += 2;
  40. tmp = "";//重来
  41. }
  42. }
  43. }
  44. cout << floor(res) << endl;
  45. return 0;
  46. }

java代码(博客中的)

  1. import java.util.Scanner;
  2. public class Main {
  3. public static void main(String[] args) {
  4. Scanner sc = new Scanner(System.in);
  5. double money = 0.0;
  6. int count = Integer.parseInt(sc.nextLine());
  7. for (int i = 0; i < count; i++) {
  8. String line = sc.nextLine();
  9. String[] split = line.split("\\d");
  10. for (String type : split) {
  11. if(!type.isEmpty()){
  12. String num = line.substring(0, line.indexOf(type));
  13. money += getCny(type, Double.parseDouble(num));
  14. line = line.substring(line.indexOf(type) + type.length());
  15. }
  16. }
  17. }
  18. System.out.println(Math.round(Math.floor(money)));
  19. }
  20. private static double getCny(String type, double num) {
  21. switch (type) {
  22. case "CNY":
  23. return num * 100;
  24. case "fen":
  25. return num;
  26. case "JPY":
  27. return num / 1825 * 10000;
  28. case "sen":
  29. return num / 1825 * 100;
  30. case "HKD":
  31. return num / 123 * 10000;
  32. case "cents":
  33. return num / 123 * 100;
  34. case "EUR":
  35. return num / 14 * 10000;
  36. case "eurocents":
  37. return num / 14 * 100;
  38. case "GBP":
  39. return num / 12 * 10000;
  40. case "pence":
  41. return num / 12 * 100;
  42. }
  43. return 0;
  44. }
  45. }

11 获得完美走位

java代码(博客中的, 我打了备注)

  1. import java.util.*;
  2. public class Main{
  3. public static void main(String[] args) {
  4. Scanner sc = new Scanner(System.in);
  5. String str = sc.nextLine();
  6. int strLen = str.length();
  7. int count = strLen / 4;
  8. Map<Character, Integer> map = new HashMap<>();
  9. //把字符串中所有的字符存到map中, k-v表示字符-个数
  10. for(int i = 0; i < strLen; i++)
  11. {
  12. char c = str.charAt(i);
  13. if(map.containsKey(c)) map.put( c, map.get(c) + 1);//保存k-v 字符-个数+1
  14. else map.put( c, 1 - count);//字符-需要的个数(用负数表示, 最后才能归0)
  15. }//比如AASW 就是 [A,1] [S,0] [W,0]
  16. int min = str.length();
  17. for (int i = 0; i < strLen; i++) {
  18. HashMap<Character, Integer> copy = new HashMap<>(map);
  19. int res = 0;
  20. if (copy.get(str.charAt(i)) > 0) //如果某个方向多走了
  21. {
  22. for (int j = i; j < str.length(); j++) //往后遍历其他的
  23. {
  24. char c = str.charAt(j);
  25. copy.put(c, copy.get(c) - 1);//把他变换一下
  26. res ++ ;//答案++
  27. if (isZero(copy)) break;//判断是否都是0
  28. }
  29. }
  30. if (isZero(copy)) res = Math.min(min, res);
  31. }
  32. System.out.println(res);
  33. }
  34. private static boolean isZero(HashMap<Character, Integer> copy) {
  35. Collection<Integer> values = copy.values();
  36. for (Integer value : values) {
  37. if (value > 0) return false;
  38. }
  39. return true;
  40. }
  41. }

12 简单的自动曝光

忽然发现我自己做的题, 不一定会满分哈哈 因为都只测了一两个用例

c++代码: 这个很简单

  1. #include <iostream>
  2. #include <cmath>
  3. #include <algorithm>
  4. using namespace std;
  5. const int N = 110;
  6. int a[N];
  7. int main(){
  8. int sum = 0;
  9. int i = 0;
  10. while(cin >> a[i]) {
  11. sum += a[i];
  12. i ++ ;
  13. }
  14. double res = (double)(512 - sum) / 4;
  15. cout << floor(res) << endl;//向下取整 1 2
  16. return 0;
  17. }

参考一下java的满分答案, 博客里面的: 

  1. import java.util.*;
  2. import java.util.Arrays;
  3. import java.util.Map;
  4. import java.util.HashMap;
  5. import java.util.stream.Stream;
  6. public class Main{
  7. public static void main(String[] args) {
  8. Scanner in = new Scanner(System.in);
  9. String[] strings = in.nextLine().split(" ");
  10. int[] nums = Arrays.stream(strings).mapToInt(Integer::parseInt).toArray();
  11. solution(nums);
  12. }
  13. public static void solution(int[] list) {
  14. int ans = 0;
  15. int t = Integer.MAX_VALUE;
  16. for (int i = -127; i < 255; ++i) {
  17. int sum = 0;
  18. for (int j = 0; j < list.length; ++j) {
  19. int tmp = i + list[j];
  20. if (tmp < 0) {
  21. tmp = 0;
  22. } else if (tmp > 255) {
  23. tmp = 255;
  24. }
  25. sum += tmp;
  26. }
  27. if (t > Math.abs(128 * list.length - sum)) {
  28. ans = i;
  29. t = Math.abs(128 * list.length - sum);
  30. }
  31. }
  32. System.out.println(ans);
  33. }
  34. }

13 日志采集系统

c++ 代码, 我觉得我写的很牛哈哈哈

  1. #include <iostream>
  2. #include <cmath>
  3. #include <algorithm>
  4. using namespace std;
  5. const int N = 1010;//最多1000个 每个里面100条
  6. int a[N], s[N], m[N];//
  7. int main(){
  8. int i = 1;
  9. while(cin >> a[i]) {
  10. s[i] = s[i - 1] + a[i];//前缀和
  11. m[i] = s[i - 1] + s[i];//要减去的
  12. //cout << s[i] << ' ' <<m[i] << endl;
  13. i ++ ;
  14. }
  15. int n = i;//总采集次数
  16. int res = 0;
  17. int score = 0;
  18. for(int i = 1; i <= n; i ++ )
  19. {
  20. score = min(100, s[i]) - m[i - 1];
  21. res = max(res, score);
  22. if(s[i] >= 100) break;
  23. }
  24. cout << res <<endl;
  25. return 0;
  26. }

java代码:

就不放了 没我写得好

14 数组的中心位置

c++ 简洁优雅, 不过可能会爆int 需要优化一下

  1. #include <iostream>
  2. #include <cmath>
  3. #include <algorithm>
  4. using namespace std;
  5. const int N = 1034;//最多1024个
  6. int a[N], s[N];
  7. int main(){
  8. int i = 1;
  9. s[0] = 1;
  10. while(cin >> a[i]) {
  11. s[i] = s[i - 1] * a[i];
  12. i ++ ;
  13. }
  14. int n = i - 1;
  15. for(int j = 1; j <= n; j ++ ) {
  16. if(s[j] * s[j + 1] == s[n]) {
  17. cout << j << endl;
  18. return 0;
  19. }
  20. }
  21. cout << "-1" << endl;
  22. return 0;
  23. }

优化:

看一下java解法 博客写的, 没动过:

  1. public class Main{
  2. public static void main(String[] args) {
  3. Scanner sc = new Scanner(System.in);
  4. String[] strings = sc.nextLine().split(" ");
  5. int len = strings.length;
  6. int[] nums = Arrays.stream(strings).mapToInt(Integer::parseInt).toArray();
  7. //题目说:数组第一个元素的左侧积为1,最后一个元素的右侧积为1
  8. int left=1, right=1;
  9. for(int num : nums){
  10. right = right * num; //数组的总乘积
  11. }
  12. boolean flag =false;
  13. for(int i=0; i<len; i++){
  14. if(i!=0){
  15. left = left * nums[i-1]; //左侧积做乘法
  16. }
  17. right = right / nums[i]; //右侧积做除法
  18. if(left == right){
  19. System.out.print(i);
  20. flag = true;
  21. break;
  22. }
  23. }
  24. if(!flag){
  25. System.out.println(-1);
  26. }
  27. }
  28. }

15 通信误码

java代码: 按照博客思路打的

  1. import java.util.*;
  2. public class Main {
  3. public static void main(String[] args) {
  4. Scanner sc = new Scanner(System.in);
  5. int n = sc.nextInt();
  6. int[] nums = new int[n];
  7. for(int i = 0; i < n; i ++ ) {
  8. nums[i] = sc.nextInt();
  9. }
  10. Map<Integer, Integer> map = new HashMap<>();//存k-v 误码-误码频率
  11. int max = 0;//数字出现的最大次数
  12. for(int i = 0; i < n; i ++ ) {
  13. int count = map.getOrDefault(nums[i], 0) + 1;//当前数字出现次数再加上1次
  14. max = Math.max(max, count);//取最大值
  15. map.put(nums[i], count);//存进map
  16. }
  17. Set<Integer> set = new HashSet<>();//存最高误码的集合
  18. for(Map.Entry<Integer, Integer> entry : map.entrySet()) {
  19. if(entry.getValue() == max) {
  20. set.add(entry.getKey());//加入频率最高的数字
  21. }
  22. }
  23. int res = n;
  24. for(Integer integer : set) {//双指针 取出某个max值,
  25. int l = 0, r = n - 1;
  26. while(nums[l] != integer) l ++ ;//当两个指针都是max值的时候才停下
  27. while(nums[r] != integer) r -- ;
  28. if(l <= r) res = Math.min(res, r - l + 1);//max取结果
  29. }
  30. System.out.println(res);
  31. }
  32. }

getOrDefault方法: 

格式:
Map.getOrDefault(key,默认值);

Map中会存储一一对应的key和value。
如果 在Map中存在key,则返回key所对应的的value。
如果 在Map中不存在key,则返回默认值。

entrySet()

Java中Map的 entrySet() 详解以及用法(四种遍历map的方式)-CSDN博客

【java笔记】java中的Map.Entry和Map.entrySet()方法的使用_map.entry<integer,integer> entry:map.entryset()_棉花糖灬的博客-CSDN博客

Map中采用Entry内部类来表示一个映射项,映射项包含Key和Value (我们总说键值对键值对, 每一个键值对也就是一个Entry)
Map.Entry里面包含getKey()和getValue()方法

entrySet是java中 键-值对的集合,Set里面的类型是Map.Entry,一般可以通过map.entrySet()得到。

  • entrySet实现了Set接口,里面存放的是键值对。一个K对应一个V。

即通过getKey()得到K,getValue得到V。

这种遍历方法比较快: 

Map.Entry<Integer, Integer> entry : map.entrySet()

16 网上商城优惠

【华为OD机试真题2023 JAVA】网上商城优惠活动(一)_接口测试主要测哪些方面_若博豆的博客-CSDN博客z

这题绕糊涂了 , 没写对, 有空重新弄一下

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <cmath>
  4. using namespace std;
  5. int mj;
  6. int dz;
  7. int wmk;
  8. int n;
  9. double manjian(int money) {
  10. int a = money / 100;//可以使用的张数
  11. int count = a > mj ? mj : a;
  12. double res = (double) (money - count * 10) ;
  13. return res;
  14. }
  15. double wumenk(int money) {
  16. int a = money / 5;//可以使用的张数
  17. int count = a > wmk ? wmk : a;
  18. double res = (double) (money - count * 5) ;
  19. return res;
  20. }
  21. int main()
  22. {
  23. scanf("%d%d%d", &mj, &dz, &wmk);
  24. scanf("%d", &n);
  25. int res;
  26. while(n -- ) {
  27. int money;
  28. scanf("%d", &money);//账单金额 操作前
  29. int res = 2e9;
  30. int tmp = 2e9;
  31. //C32 6中情况 打折只能用一次, 其他的无使用限制
  32. //先满减后打折
  33. if(mj > 0 && dz > 0) {
  34. tmp = manjian(money);
  35. tmp = floor((double)tmp * 0.92);
  36. }
  37. res = min(res, tmp);
  38. //先满减后无门槛
  39. if(mj > 0 && wmk > 0) {
  40. tmp = manjian(money);
  41. tmp = wumenk(tmp);
  42. }
  43. res = min(res, tmp);
  44. //先打折后满减
  45. if(dz > 0 && mj > 0) {
  46. tmp = floor(money * 0.92);
  47. tmp = manjian(tmp);
  48. }
  49. res = min(res, tmp);
  50. //先打折后无门槛
  51. if(dz > 0 && wmk > 0) {
  52. tmp = floor((double)tmp * 0.92);
  53. tmp = wumenk(tmp);
  54. }
  55. res = min(res, tmp);
  56. //先无门槛后满减
  57. if(mj > 0 && wmk > 0) {
  58. tmp = wumenk(tmp);
  59. tmp = manjian(money);
  60. }
  61. res = min(res, tmp);
  62. //先无门槛后打折
  63. if(dz > 0 && wmk > 0) {
  64. tmp = wumenk(tmp);
  65. tmp = floor((double)tmp * 0.92);
  66. }
  67. res = min(res, tmp);
  68. cout << res << endl;
  69. }
  70. return 0;
  71. }

java博客代码

  1. import java.util.Scanner;
  2. public class Main{
  3. public static int manjian;
  4. public static int dazhe;
  5. public static int wumenkan;
  6. //券的最小使用量
  7. public static int mincountQuan;
  8. //最少价格
  9. public static int minCount;
  10. public static void main(String[] args) {
  11. Scanner sc = new Scanner(System.in);
  12. manjian = sc.nextInt();
  13. dazhe = sc.nextInt();
  14. wumenkan = sc.nextInt();
  15. int n = sc.nextInt();
  16. for(int i=0; i<n; i++){
  17. double money = sc.nextInt();
  18. //首先使用满减的张数
  19. int quanMJ = money/100 > manjian ? manjian : (int) (money / 100);
  20. //使用无门槛的券的张数
  21. int quanWMK;
  22. //券的最小使用量
  23. mincountQuan = Integer.MAX_VALUE;
  24. //最少价格
  25. minCount = Integer.MAX_VALUE;
  26. if(dazhe > 0){ //有打折券的情况
  27. //先满减后打折
  28. int MJafterDZ = (int) Math.floor(Manjian(money) * 0.92);
  29. flush( MJafterDZ, quanMJ + 1);
  30. //先打折后满减
  31. int DZafterMJ = (int) Math.floor(Manjian(money * 0.92));
  32. //先打折后满减的满减券
  33. int quanDZafterMJ = (int) (money * 0.92 / 100 > manjian ? manjian : money * 0.92 / 100);
  34. flush( DZafterMJ, quanDZafterMJ + 1);
  35. //先打折后无门槛
  36. double dazhe = money * 0.92;
  37. //无门槛需要的张数
  38. quanWMK = wumenkan(dazhe);
  39. int dazheWMK;
  40. if(dazhe <= quanWMK * 5){
  41. //打折后的价格小于等于无门槛的全部价格(可以0元购)
  42. dazheWMK = 0;
  43. }else {
  44. dazheWMK = (int) Math.floor(dazhe - quanWMK * 5);
  45. }
  46. flush( dazheWMK, quanWMK + 1);
  47. //先无门槛后打折
  48. int wmkDZ;
  49. //无门槛需要的张数
  50. quanWMK = wumenkan(money);
  51. if(money <= quanWMK * 5 ){
  52. //价格小于等于无门槛的全部价格(可以0元购)
  53. flush( 0, quanWMK);
  54. }else {
  55. wmkDZ = (int) Math.floor((money - quanWMK * 5) * 0.92);
  56. flush( wmkDZ, quanWMK + 1);
  57. }
  58. }
  59. //先满减后无门槛
  60. int mjWMK;
  61. double manjian= Manjian(money);
  62. //无门槛需要的张数
  63. quanWMK = wumenkan(manjian);
  64. if(manjian <= quanWMK * 5){
  65. //满减后的价格小于等于无门槛的全部价格(可以0元购)
  66. mjWMK = 0;
  67. }else {
  68. mjWMK = (int) Math.floor(manjian - quanWMK * 5);
  69. }
  70. flush( mjWMK, quanWMK + quanMJ);
  71. System.out.println(minCount + " " + mincountQuan);
  72. }
  73. }
  74. /**
  75. * 刷新最少价格和最少使用券
  76. * @param count
  77. * @param quanCount
  78. */
  79. public static void flush(int count, int quanCount){
  80. if(count < minCount){
  81. minCount = count;
  82. mincountQuan = quanCount;
  83. }else if(count == minCount){
  84. mincountQuan = Math.min( quanCount, mincountQuan);
  85. }
  86. }
  87. /**
  88. * 求出需要无门槛优惠券的张数
  89. * @param money
  90. * @return
  91. */
  92. public static int wumenkan(double money){
  93. for(int i=1; i<=wumenkan; i++){
  94. if(money <= 5 * i) {
  95. return i;
  96. }
  97. }
  98. return wumenkan;
  99. }
  100. /**
  101. * 满减后的价格
  102. * @param money
  103. * @return
  104. */
  105. public static double Manjian(double money){
  106. if(money/100 >= manjian){
  107. return money - manjian*10;
  108. }else {
  109. return money - ((int) money/100)*10;
  110. }
  111. }
  112. }

17 开心消消乐

java代码

感觉这个没有回溯啊 就是找到第一个点来计算的.. 有空看吧 先记住了

  1. import java.util.Scanner;
  2. public class Main {
  3. public static void main(String[] args) {
  4. Scanner scanner = new Scanner(System.in);
  5. int row = scanner.nextInt();
  6. int column = scanner.nextInt();
  7. int[][] numbers = new int[row][column];
  8. scanner.nextLine();
  9. for (int i = 0; i < row; i++) {//每行
  10. for (int j = 0; j < column; j++) {
  11. numbers[i][j] = scanner.nextInt();
  12. }
  13. }
  14. int count = 0;
  15. for (int i = 0; i < row; i++) {
  16. for (int j = 0; j < column; j++) {
  17. if (numbers[i][j] == 1) {//如果该点值为1 点击一下, 再继续循环其他的点
  18. turnZero(numbers, row, column, i, j);
  19. count++;
  20. }
  21. }
  22. }
  23. System.out.println(count);
  24. }
  25. private static void turnZero(int[][] numbers, int row, int col, int x, int y) {
  26. numbers[x][y] = 0;//点击为0
  27. for (int i = x - 1; i <= x + 1; i ++ ) {
  28. for (int j = y - 1; j <= y + 1; j ++ ) {//遍历相邻的8个点
  29. if (i >= 0 && i < row && j >= 0 && j < col && numbers[i][j] == 1) {//如果是1
  30. turnZero(numbers, row, col, i, j);//就自动变为0
  31. }
  32. }
  33. }
  34. }
  35. }

18 获取最大软件版本号

compareTo 复习一下

java中compareTo方法的使用_compareto在java中的用法_高某123的博客-CSDN博客

 java代码: 

  1. import java.util.*;
  2. public class Main {
  3. public static void main(String[] args) {
  4. Scanner scanner = new Scanner(System.in);
  5. String a = scanner.nextLine();
  6. String b = scanner.nextLine();
  7. String[] strs1 = a.split("\\.");//1.5.1-A 分成 1 5 1-A
  8. String[] strs2 = b.split("\\.");
  9. //比较主次版本 1.3.11-S2 1.05.1 中的 1 3 和 1 05 挨个遍历这两个字符
  10. for(int i = 0; i < 2; i ++ ) {
  11. int va = Integer.valueOf(strs1[i]);
  12. int vb = Integer.valueOf(strs2[i]);
  13. if(va != vb) {//继续遍历
  14. System.out.println(va > vb ? a : b);
  15. return;
  16. }
  17. }
  18. //增量版本可能不存在 如 直接是 1.5
  19. //比较增量版本 和里程碑版本
  20. if(strs1.length > 2 && strs2.length > 2 ) {//两个版本长度都 > 2
  21. //有增量版本 就在strs[2]位置
  22. String[] s1 = strs1[2].split("-"); //分成 1 A
  23. String[] s2 = strs2[2].split("-");
  24. int va = Integer.valueOf(s1[0]);
  25. int vb = Integer.valueOf(s2[0]);
  26. if(va != vb) {
  27. System.out.println(va > vb ? va : vb);
  28. return;
  29. }
  30. //增量版本也相同 如果都有里程碑版本
  31. if(s1.length == 2 && s2.length == 2) {
  32. //字典序排序 compareTo
  33. System.out.println(s1[1].compareTo(s2[1]) >= 0 ? a : b);
  34. } else {
  35. System.out.println(s2.length >= s2.length ? a : b);
  36. }
  37. } else {
  38. System.out.println(strs1.length >= strs2.length ? a : b);
  39. }
  40. }
  41. }

19 寻找链表的中间节点

输入:

00100 4
00000 4 -1
00100 1 12309
33218 3 00000
12309 2 33218

输出: 3

输入:

10000 3
76892 7 12309
12309 5 -1
10000 1 76892

输出: 7

java代码: 博客里的 我打了备注

  1. import java.util.*;
  2. public class Main {
  3. public static class Node{
  4. String data;
  5. String next;
  6. public Node(String data, String next) {
  7. this.data = data;
  8. this.next = next;
  9. }
  10. }
  11. public static void main(String[] args) {
  12. //保存 地址 - 节点
  13. Map<String, Node> map = new HashMap<>();
  14. Scanner sc = new Scanner(System.in);
  15. //初始化元信息
  16. String[] mate = sc.nextLine().split(" "); //mate[0] 是 地址 mate[1] 是个数
  17. for(int i = 0; i < Integer.parseInt(mate[1]); i ++ ) {
  18. String[] info = sc.nextLine().split(" ");//每一行的地址 value next
  19. map.put(info[0], new Node(info[1], info[2]));
  20. }
  21. //通过list保存有效数据和记录数据链长度
  22. List<String> res = new LinkedList<>();//保存结果 list是有序的
  23. String address = mate[0];//起始地址是第一个
  24. while(true) {
  25. if(map.containsKey(address) == false) break;
  26. //不包含起始地址, 链表为空; 或者找不到下一个地址, 链表结束
  27. Node node = map.get(address);//get(Key) 得到的v就是 Node
  28. res.add(node.data);//链表保存数据
  29. address = node.next;//address记录下一个node
  30. }
  31. //返回中间位置的值
  32. int idx = res.size() / 2;
  33. System.out.println(res.get(idx));
  34. }
  35. }

20 最小的调整次数

输入:

3
head add 1
remove 
tail add 2
head add 3
remove 
remove

输出: 1

java代码

  1. import java.util.*;
  2. public class Main {
  3. public static void main(String[] args) {
  4. Scanner sc = new Scanner(System.in);
  5. int n = Integer.parseInt(sc.nextLine());//读取数据范围
  6. int cnt = 0;//变幻的次数
  7. int left = 0;//剩下待移除的数字
  8. boolean flag = false;//是否需要逆转
  9. //2n 行
  10. for(int i = 0; i < 2 * n; i ++ ) {
  11. //读取一行 head add 1 或者 remove
  12. String[] str = sc.nextLine().split(" ");
  13. if(str.length == 3 ) {//add操作
  14. if(left != 0) {//有数字的情况下
  15. //如果是head, 就要调整一次顺序
  16. if(str[0].equals("head") && !flag ) { //不需要调整
  17. flag = true;//标记需要调整
  18. }
  19. //如果是tail, 不用管, 直接添加
  20. }
  21. //如果left==0, 不管头和尾都直接添加
  22. left ++ ;//数字添加
  23. }
  24. if(str.length == 1) {//移除操作
  25. left -- ;//数字减少
  26. cnt += flag ? 1 : 0;//是不是需要调整, 需要的话结果+1
  27. flag = false;//调整完结束
  28. }
  29. }
  30. System.out.println(cnt);
  31. }
  32. }

这个题目的意思是 一次调整可以调整所有的数, 所以一直等待一个head插入就可以计数了

21 字符串解密

java代码 自己打了备注

  1. import java.util.*;
  2. public class Main {
  3. public static void main(String[] args) {
  4. Scanner sc = new Scanner(System.in);
  5. String s1 = sc.nextLine();
  6. String s2 = sc.nextLine();
  7. //处理字符串2
  8. HashSet<String> set = new HashSet<>();
  9. for(char c : s2.toCharArray()) {//把字符串2变成字符数组 遍历每个字符
  10. set.add(c + "");//把每个字符都存到set中 set是自动去重的
  11. }
  12. //处理字符串1
  13. String sub = "123456789abcdef";
  14. //去掉0-9 a-f
  15. int index = 0;//起始点
  16. ArrayList<String> list = new ArrayList<>();//保存删除0-9 a-f后的 字符串数组
  17. //保存筛选后的字符串
  18. for(int i = 0; i < s1.length(); i ++ ) {
  19. if(sub.contains(s1.charAt(i) + "")) {//遍历到0-9 a-f时, 保存当前字符串
  20. list.add(s1.substring(index, i));//substring(1,1)是空, 所以不保存
  21. index = i + 1;
  22. } else {
  23. if(i == s1.length() - 1) { //遍历到结尾的时候
  24. list.add(s1.substring(index));
  25. }
  26. }
  27. }
  28. String res = "";
  29. for(int i = 0; i < list.size(); i ++) {//枚举i 获得每个子字符串
  30. String cs = list.get(i);//list里面每个子字符串
  31. if(cs.length > 0) {
  32. //hashset会自动去重, 获得的长度就是去重后的
  33. HashSet<String> cset = new HashSet<>();
  34. for(int j = 0; j < cs.length(); j++ ) {
  35. cset.add(cs.charAt(j) + "" );
  36. }
  37. int len = cset.size();//去重后 每个子串的长度
  38. //如果这个子串满足题目要求的条件: < 字符串2的长度
  39. if (len <= set.size()) {
  40. //就把结果字符串去重
  41. HashSet<String> sset = new HashSet<>();
  42. for (int j = 0; j < res.length(); j++) {
  43. sset.add(res.charAt(j) + "");
  44. }
  45. int slen = sset.size();
  46. //如果子串长度 > 结果串长度, 更新结果
  47. if (len > slen) {
  48. res = cs;
  49. } else if (len == slen && cs.compareTo(res) > 0) {//字典序
  50. res = cs;//如果子串长度相同, 字典序更大 也更新结果
  51. }
  52. }
  53. }
  54. }
  55. if (res.length() > 0) {
  56. System.out.println(res);
  57. } else {
  58. System.out.println("Not Found");
  59. }
  60. }
  61. }

22 投篮大赛

java代码

  1. import java.util.*;
  2. public class Main {
  3. public static void main(String[] args) {
  4. Scanner sc = new Scanner(System.in);
  5. String s = sc.nextLine();
  6. String[] nums = s.split(" ");
  7. List<Integer> list = new ArrayList<>();
  8. int res = 0;
  9. for(int i = 0; i < nums.length; i ++ ) {//遍历每个串
  10. if(nums[i].equals("+")) {
  11. int j = list.size();
  12. if(list.size() < 2) {//需要集合 >= 2 才能+
  13. System.out.println("-1");
  14. return;
  15. }
  16. int grade = list.get(j - 1) + list.get(j - 2);//倒数第一个和倒数第二个
  17. list.add(grade);
  18. } else if (nums[i].equals("D")) {
  19. int j = list.size();
  20. if(list.size() < 1) {//需要集合 >= 1 需要前面有一个数字
  21. System.out.println("-1");
  22. return;
  23. }
  24. int grade = list.get(j - 1) * 2;
  25. list.add(grade);
  26. } else if(nums[i].equals("C") ) {
  27. if(list.size() < 1 ) {//需要集合 >= 1 前面有1个数据
  28. System.out.println("-1");
  29. return;
  30. }
  31. list.remove(list.size() - 1);//去掉最后一个数字
  32. } else {//直接添加
  33. list.add(new Integer(nums[i]));
  34. }
  35. }
  36. for(int i = 0; i < list.size(); i ++ ) {
  37. res += list.get(i);
  38. }
  39. System.out.println(res);
  40. }
  41. }

23 任务总执行时长

java 

咱们就是说, 我只会写这种

  1. // 本题为考试单行多行输入输出规范示例,无需提交,不计分。
  2. import java.util.*;
  3. public class Main {
  4. public static void main(String[] args) {
  5. Scanner in = new Scanner(System.in);
  6. String[] input = in.nextLine().split(",");
  7. int taskA = Integer.valueOf(input[0]);
  8. int taskB = Integer.valueOf(input[1]);
  9. int nums = Integer.valueOf(input[2]);
  10. HashSet<Integer> set = new HashSet<>();
  11. if(nums != 0){
  12. int countA = nums;
  13. while(countA >= 0){
  14. int countB = nums - countA;
  15. set.add(countA * taskA + countB * taskB);
  16. countA -- ;
  17. }
  18. }
  19. List<Integer> ans = new ArrayList<>(set);
  20. Collections.sort(ans);
  21. System.out.println(ans);
  22. }
  23. }

24 找数字

java

这个可以看下原链接 满分解法 好像写的更好, 没来得及看

  1. import java.util.*;
  2. //找数字
  3. public class Main {
  4. public static void main(String[] args) {
  5. Scanner sc = new Scanner(System.in);
  6. int row = sc.nextInt();
  7. int col = sc.nextInt();
  8. int[][] nums = new int[row][col];
  9. for(int i = 0; i < row; i ++ ) {
  10. for(int j = 0; j < col; j ++ ) {
  11. nums[i][j] = sc.nextInt();
  12. }
  13. }
  14. HashMap<Integer, List<int[]>> map = new HashMap<>();//存<数字, {{坐标}, {坐标} ..}>
  15. for(int i = 0; i < row; i ++ ) {
  16. for(int j = 0; j < col; j ++ ) {
  17. List<int[]> list;
  18. if(map.containsKey(nums[i][j])) {
  19. list = map.get(nums[i][j]);
  20. } else {
  21. list = new ArrayList<>();
  22. }
  23. list.add(new int[]{i, j});
  24. map.put(nums[i][j], list);
  25. }
  26. }
  27. ArrayList<List<Integer>> resList = new ArrayList<>();
  28. for(int i = 0; i < row; i ++ ) {
  29. ArrayList<Integer> row_list = new ArrayList<>();//一行的结果
  30. for(int j = 0; j < col; j ++ ) {//该行每个数字
  31. int key = nums[i][j];
  32. List<int[]> sites = map.get(key);//每个数字的坐标集合
  33. if(sites.size() == 1) {
  34. row_list.add(-1);
  35. continue;//遍历下一个数字
  36. }
  37. int res = Integer.MAX_VALUE;
  38. //当坐标集合>1时 遍历每个集合
  39. for(int k = 0; k < sites.size(); k ++ ) {
  40. int[] ints = sites.get(k);
  41. int x = ints[0];
  42. int y = ints[1];
  43. //距离
  44. int distance = Math.abs(x - i) + Math.abs(y - j);
  45. if(distance == 0) continue;//否则把自己比较进去了 0 也会影响结果
  46. res = Math.min(distance, res);//每个结果都更新
  47. }
  48. row_list.add(res);
  49. }
  50. resList.add(row_list);
  51. }
  52. System.out.println(resList);
  53. }
  54. }

26 箱子之形摆放

java

map存<位置, 结果字符串> 

  1. import java.util.*;
  2. //26 箱子的摆放
  3. public class Main {
  4. public static void main(String[] args) {
  5. Scanner sc = new Scanner(System.in);
  6. String[] strings = sc.nextLine().split(" ");
  7. String str = strings[0];
  8. int n = Integer.parseInt(strings[1]);
  9. char[] chars = str.toCharArray();
  10. //用map存每一行
  11. //k-v是 <Integer. String>
  12. // key是行数, values每一行的内容 把该位置的字符拼到values
  13. HashMap<Integer, String> res = new HashMap<>();//<0,A> <1,B> <2,C>
  14. for(int i = 0 ; i < str.length(); i += n ) {
  15. if(i / n % 2 == 0) {//偶数列 正序
  16. for(int j = 0; j < n; j ++ ) {
  17. if(i + j < str.length()) {
  18. if(res.containsKey(j)) {
  19. String value = res.get(j);//必须要判断 否则会把null加进去
  20. value += str.charAt(j + i);
  21. res.put(j, value);
  22. } else {
  23. res.put(j, String.valueOf(str.charAt(j + i)));
  24. }
  25. }
  26. }
  27. } else {//奇数 倒序
  28. for(int j = 0; j < n; j ++ ) {
  29. if(res.containsKey(j)) {
  30. String value = res.get(n - 1 - j);
  31. value += str.charAt(j + i);
  32. res.put(n - 1 - j, value);
  33. } else {
  34. res.put(n - 1 - j, String.valueOf(str.charAt(j + i)));
  35. }
  36. }
  37. }
  38. }
  39. for(String sb: res.values()) {
  40. System.out.println(sb);
  41. }
  42. // for(Map.Entry<Integer, String> map : res.entrySet()) {
  43. // System.out.println(map.getValue());
  44. // }
  45. }
  46. }

27 异常的打卡记录

java

  1. import java.util.*;
  2. //找数字
  3. public class Main {
  4. public static void main(String[] args) {
  5. Scanner sc = new Scanner(System.in);
  6. int n = sc.nextInt();//打卡记录数
  7. sc.nextLine();
  8. HashMap<Integer, List<int[]>> map = new HashMap<>();
  9. //遍历每个打卡记录
  10. ArrayList<String> alls = new ArrayList<>();
  11. for(int i = 0; i < n; i ++ ) {
  12. String str = sc.nextLine();
  13. //System.out.println(str);
  14. String[] strings = str.split(",");
  15. alls.add(str);
  16. int id = Integer.parseInt(strings[0]);
  17. int time = Integer.parseInt(strings[1]);
  18. int distance = Integer.parseInt(strings[2]);
  19. if(map.containsKey(id)) {
  20. List<int[]> list = map.get(id);
  21. list.add(new int[]{time, distance});
  22. map.put(id, list);
  23. } else {
  24. ArrayList<int[]> list = new ArrayList<>();
  25. list.add(new int[]{time, distance});
  26. map.put(id, list);
  27. }
  28. }
  29. ArrayList<Integer> res = new ArrayList<>();
  30. //遍历每个map 找重复打卡的人是不是有异常
  31. for(Map.Entry<Integer, List<int[]>> entry : map.entrySet()) {
  32. Integer id = entry.getKey();
  33. List<int[]> list = entry.getValue();//{时间, 地点} {} {} ..
  34. // if(list.size() == 1) {
  35. // //打卡记录一次, 不存在两次打卡距离的问题
  36. // //判断内部是否需要检查
  37. // }
  38. if(list.size() != 1) {//比较 任意两个数组
  39. for(int i = 0; i < list.size() - 1; i ++ ) {
  40. int[] ints = list.get(i);
  41. int time1 = ints[0];
  42. int distance1 = ints[1];
  43. for(int j = i + 1; i < list.size(); i ++ ) {
  44. int[] ints2 = list.get(i);
  45. int time2 = ints2[0];
  46. int distance2 = ints2[1];
  47. if(Math.abs(time1 - time2) < 60
  48. && Math.abs(distance1 - distance2) > 5) {
  49. res.add(id);
  50. }
  51. }
  52. }
  53. }
  54. }
  55. //遍历每个打卡记录 集合alls里面的
  56. boolean flag = true;
  57. StringBuilder ans = new StringBuilder();
  58. for(int i = 0; i < n; i ++ ) {
  59. String str = alls.get(i);
  60. String[] strings = str.split(",");
  61. int id = Integer.parseInt(strings[0]);
  62. String log = strings[3];
  63. String register = strings[4];
  64. if(res.contains(id)) {
  65. //System.out.println(str);
  66. ans.append(str);
  67. ans.append(" ");
  68. flag = false;
  69. } else if(!log.equals(register)) {
  70. //System.out.println(str);
  71. ans.append(str);
  72. ans.append(" ");
  73. flag = false;
  74. }
  75. }
  76. if(flag) System.out.println("null");
  77. else System.out.println(ans.toString().trim().replace(" ", ";"));
  78. }
  79. }

28 最左侧冗余覆盖子串

  1. import java.util.*;
  2. //28 最左侧冗余覆盖子串
  3. public class Main {
  4. public static void main(String[] args) {
  5. Scanner sc = new Scanner(System.in);
  6. String s1 = sc.nextLine();
  7. String s2 = sc.nextLine();
  8. int k = sc.nextInt();
  9. int n1 = s1.length();
  10. int n2 = s2.length();
  11. int len = n1 + k;
  12. for(int i = 0; i < n2 - len + 1; i ++ ) {//枚举子串开始的下标
  13. String tmp = "";
  14. for(int j = 0; j < len; j ++ ) {//子串长度
  15. tmp += s2.charAt(j + i);
  16. }
  17. if(tmp.contains(s1)) {
  18. System.out.println(i);
  19. return;
  20. }
  21. }
  22. System.out.println("-1");
  23. }
  24. }

或者substring

  1. for(int i = 0; i < n2 - len + 1; i ++ ) {//枚举子串开始的下标
  2. String tmp = s2.substring(i, i + len);
  3. if(tmp.contains(s1)) {
  4. System.out.println(i);
  5. return;
  6. }
  7. }

29 最多提取子串数目

  1. import java.util.*;
  2. //29 最多提取子串数目
  3. public class Main {
  4. public static void main(String[] args) {
  5. Scanner sc = new Scanner(System.in);
  6. String stra = sc.nextLine();//父字符串
  7. String strb = sc.nextLine();
  8. //char[] charsa = stra.toCharArray();//父字符串的字符数组
  9. int len = stra.length();
  10. int[] a = new int[len];//数组 保存是否已经被取过 0/1 没取过 是 0
  11. int i = 0, j = 0;
  12. int cnt = 0;
  13. while (i < stra.length()) {
  14. if (stra.charAt(i) == strb.charAt(j) && a[i] == 0) {//匹配上了
  15. a[i] = 1;
  16. //匹配上了 需要判断: 如果匹配完子串, 父串从0开始, 否则父串i++往后移动
  17. j ++ ;//子串往后移动
  18. }
  19. if (j == strb.length()) {//子串遍历到尾巴了 说明都匹配上了
  20. cnt ++ ;
  21. j = 0;
  22. i = 0;
  23. } else {
  24. i ++ ;//父串继续往后遍历
  25. }
  26. }
  27. System.out.println(cnt);
  28. }
  29. }

30 找出通过车辆最多颜色

java: 

  1. import java.util.*;
  2. public class Main {
  3. public static void main(String[] args) {
  4. Scanner sc = new Scanner(System.in);
  5. String[] strings = sc.nextLine().split(" ");
  6. int n = sc.nextInt();//n秒时间
  7. int res = 0;
  8. for(int i = 0; i < strings.length - n + 1; i ++ ) {
  9. //类似滑动窗口, 遍历每个窗口
  10. int[] ints = new int[3];//3中颜色
  11. for(int j = i; j < n; j ++ ) {
  12. int num = Integer.parseInt(strings[j]);
  13. ints[num] ++ ;
  14. }//遍历完得到这个窗口的每个颜色个数
  15. int max = Arrays.stream(ints).max().getAsInt();
  16. //Arrays.stream(intArr); 转成int流, 可以求sum max min average()
  17. res = Math.max(res, max);
  18. }
  19. System.out.println(res);
  20. }
  21. }

31 优秀学员统计

java

  1. import java.util.*;
  2. //26 箱子的摆放
  3. public class Main {
  4. public static void main(String[] args) {
  5. Scanner sc = new Scanner(System.in);
  6. int n = sc.nextInt();//员工数量
  7. //sc.nextLine();
  8. int[] nums = new int[30];//30天 每天打卡人数
  9. for (int i = 0; i < 30; i++) {
  10. nums[i] = sc.nextInt();//第i的打卡人数
  11. }
  12. //int[] cnts = new int[n];//下标是id, 大小是打卡次数
  13. //换成用map存 <Integer, int[]> <id, {最早打卡时间, 打卡天数}>
  14. //用map存, <integer, int[2]> 员工工号 - (第一次打卡时间, 打卡数)
  15. HashMap<Integer, int[]> res = new HashMap<>();
  16. for (int i = 0; i < 30; i++) {//循环30天
  17. for(int j = 0; j < nums[i]; j ++ ) {
  18. int id = sc.nextInt();
  19. if(res.containsKey(id)) {//包含这个员工
  20. int[] tmp = res.get(id);
  21. tmp[1] ++;
  22. res.put(id, tmp);
  23. } else {
  24. int[] tmp = new int[2];
  25. tmp[0] = i;
  26. tmp[1] = 1;
  27. res.put(id, tmp);
  28. }
  29. }
  30. }
  31. List<Map.Entry<Integer, int[]>> resList = new ArrayList<>(res.entrySet());
  32. resList.sort(new Comparator<Map.Entry<Integer, int[]>>() {
  33. @Override
  34. public int compare(Map.Entry<Integer, int[]> o1, Map.Entry<Integer, int[]> o2) {
  35. if(o1.getValue()[1] == o2.getValue()[1]) {
  36. return o1.getValue()[0] - o2.getValue()[0];//按照打卡时间 从小到大
  37. } else {
  38. return o2.getValue()[1] - o1.getValue()[1];//按照打卡天数 从大到小
  39. }
  40. }
  41. });
  42. StringBuilder ans = new StringBuilder();
  43. for(int i = 0; i < (Math.min(resList.size(), 5)); i ++ ) {//前五 员工 的 id
  44. ans.append(resList.get(i).getKey()).append(" ");
  45. }
  46. System.out.println(ans.substring(0, ans.length() - 1));
  47. }
  48. }

考的时候写的 救命 紧张了 写的比原来复杂, 不过也是满分 

  1. import java.util.*;
  2. public class Main {
  3. public static void main(String[] args) {
  4. Scanner sc = new Scanner(System.in);
  5. /*
  6. 11
  7. 4 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2
  8. 0 1 7 10
  9. 0 1 6 10
  10. 10
  11. 10
  12. 10
  13. 10
  14. 10
  15. 10
  16. 10
  17. 10
  18. 10
  19. 10
  20. 10
  21. 10
  22. 10
  23. 10
  24. 10
  25. 10
  26. 10
  27. 10
  28. 10
  29. 10
  30. 10
  31. 10
  32. 10
  33. 10
  34. 10
  35. 10
  36. 6 10
  37. 7 10
  38. */
  39. //员工情况 int[]
  40. int n = sc.nextInt();//新员工数量
  41. int[] empls = new int[30];//每天打卡的员工数量
  42. for(int i = 0; i < 30; i ++ ) {
  43. empls[i] = sc.nextInt();
  44. }
  45. int[] cnts = new int[n];//保存员工打卡的数量
  46. int[] first = new int[n];
  47. for(int i = 0; i < 30; i ++ ) {//天数
  48. for(int j = 0; j < empls[i]; j ++ ){
  49. int id = sc.nextInt();//员工编号
  50. if(cnts[id] == 0) first[id] = i;
  51. cnts[id] ++ ;
  52. }
  53. }
  54. //map <员工id, 员工打卡情况int[]{最早打卡时间, 打卡总数}>
  55. HashMap<Integer, int[]> map = new HashMap<>();
  56. for(int i = 0; i < n; i ++ ) {
  57. int days = cnts[i];//每个员工打卡次数
  58. int date = first[i];//最早打卡日期
  59. //i是员工id
  60. int[] ints = new int[2];
  61. ints[0] = date;
  62. ints[1] = days;
  63. map.put(i, ints);
  64. }
  65. ArrayList<Map.Entry<Integer, int[]>> list = new ArrayList<>(map.entrySet());
  66. list.sort(new Comparator<Map.Entry<Integer, int[]>>() {
  67. @Override
  68. public int compare(Map.Entry<Integer, int[]> o1, Map.Entry<Integer, int[]> o2) {
  69. if(o1.getValue()[1] == o2.getValue()[1]) {//打卡次数相同时候
  70. if(o1.getValue()[0] == o2.getValue()[0]) {//打卡时间相同
  71. return o1.getKey() - o2.getKey();//打卡id较小的员工
  72. }
  73. return o1.getValue()[0] - o2.getValue()[0];//较早打卡的员工排在前
  74. }
  75. return o2.getValue()[1] - o1.getValue()[1];//打卡次数
  76. }
  77. });
  78. String res = "";
  79. int len = Math.min(5, list.size());
  80. for(int i = 0; i < len; i ++ ) {
  81. res += list.get(i).getKey();
  82. if(i != len - 1) res += " ";
  83. }
  84. System.out.println(res);
  85. }
  86. }

32 租车骑绿道

java 我写的

  1. import java.util.*;
  2. //32 租车骑绿道
  3. public class Main {
  4. public static void main(String[] args) {
  5. Scanner sc = new Scanner(System.in);
  6. int m = sc.nextInt();//限重m
  7. int n = sc.nextInt();//人数n
  8. int[] a = new int[n];
  9. for (int i = 0; i < n; i++) {
  10. a[i] = sc.nextInt();//每个人的体重
  11. }
  12. Arrays.sort(a);//从小到大排序
  13. int cnt = 0;
  14. int[] flag = new int[n]; //0
  15. //双指针遍历 一个从小到大, 一个从大到小
  16. int i = 0, j = n - 1;
  17. while (i < j) {
  18. //如果和超过限制了
  19. if (a[i] + a[j] > m) {
  20. cnt ++ ;//给最后一个++一辆车
  21. flag[j] = 1;
  22. j--;
  23. }
  24. if (a[i] + a[j] <= m) {
  25. cnt++;//给i和 j 分配 一辆车
  26. flag[i] = 1;
  27. flag[j] = 1;
  28. i++;
  29. j--;
  30. }
  31. }
  32. if(flag[i] == 0) cnt ++;//以防最中间剩下一个 没加上//比如 1 1 2 2 3 4 4 4 5 5, 剩下2
  33. System.out.println(cnt);
  34. }
  35. }

33 相同数字的积木游戏

我写的: 

  1. import java.util.*;
  2. import java.util.stream.Stream;
  3. //33 相同数字的积木游戏
  4. public class Main {
  5. public static void main(String[] args) {
  6. Scanner sc = new Scanner(System.in);
  7. int n = sc.nextInt();
  8. int[] a = new int[n];
  9. for(int i = 0; i < n; i ++ ) {
  10. int num = sc.nextInt();
  11. a[i] = num;//存进数组
  12. }
  13. //双指针 一个从前往后遍历 一个从后往前遍历
  14. //结果保存到res
  15. int res = -1;
  16. for(int i = 0; i < n; i ++ ) {
  17. int tmp = a[i];
  18. for(int j = n - 1; j > i; j -- ) {
  19. if(tmp == a[j]) {
  20. res = Math.max(res, j - i);
  21. break;
  22. }
  23. }
  24. }
  25. System.out.println(res);
  26. }
  27. }

考试时候写的 , 救命 一紧张又写复杂了

  1. import java.util.*;
  2. public class Main {
  3. public static void main(String[] args) {
  4. Scanner sc = new Scanner(System.in);
  5. int n = sc.nextInt();
  6. HashMap<Integer, List<Integer>> map = new HashMap<>();//存<数字, 位置int>
  7. for(int i = 0 ; i < n; i ++ ) {
  8. int tmp = sc.nextInt();
  9. if(map.containsKey(tmp)) {
  10. List<Integer> list = map.get(tmp);
  11. list.add(i);
  12. map.put(tmp, list);
  13. } else {
  14. ArrayList<Integer> list = new ArrayList<>();
  15. list.add(i);
  16. map.put(tmp, list);
  17. }
  18. }
  19. boolean flag = true;
  20. int ans = -1;
  21. for(Map.Entry<Integer, List<Integer>> entry : map.entrySet()) {
  22. List<Integer> list = entry.getValue();
  23. if(list.size() > 1) {
  24. flag = false;
  25. int res = 0;
  26. int len = list.size();
  27. for(int i = 0; i < len - 1; i ++ ) {
  28. for(int j = i + 1; j < len; j ++ ) {
  29. //遍历 得到一个数字的最大距离
  30. res = Math.max(res, list.get(j) - list.get(i));
  31. }
  32. }
  33. //每个数字的最大距离都更新
  34. ans = Math.max(res, ans);
  35. }
  36. }
  37. System.out.println(ans);
  38. }
  39. }

java满分答案:

  1. import java.util.Scanner;
  2. public class Main {
  3. public static void main(String[] args) {
  4. Scanner in = new Scanner(System.in);
  5. int num = in.nextInt();
  6. int[] arr = new int[num];
  7. for(int i=0;i<num;i++){
  8. arr[i] = in.nextInt();
  9. }
  10. int max=-1;
  11. for(int i=0;i<num;i++){
  12. for(int j=i+1;j<num;j++){
  13. if(arr[i]==arr[j]){
  14. max = Math.max(max,j-i);
  15. }
  16. }
  17. }
  18. System.out.println(max);
  19. }
  20. }

34工作安排

01背包问题

f[i][j]表示只考虑前i个物品, 总体不超过j的情况下, 总价值最大是多少

状态转移 f[i][j]

        1.不选第i个物品: f[i][j] = f[i - 1][j]

        2.选第i个物品: f[i][j] = f[i - 1][j - v[i]] + w[i]

        装不下的时候 f[i][j] = f[i - 1][j] (这个情况是一定存在的

        能装下的时候, 可以选或者不选, f[i][j] = max(第一种情况, 第二种情况)   (这个情况不一定存在 要判断)

f[0][0] = 0 默认0 初始化不需要写了

c++ 代码

  1. #include <iostream>
  2. #include <algorithm>
  3. using namespace std;
  4. //01背包 二维数组做法
  5. const int N = 1010;
  6. int n, m; // 物品数量, 背包容量
  7. int v[N], w[N]; // 体积 价值
  8. int f[N][N]; // f[i][j], 前 i 个物品中体积不超过 j 的最大价值
  9. int main()
  10. {
  11. cin >> m >> n;// 输入物品数量n, 背包容量m
  12. for (int i = 1; i <= n; i++) cin >> v[i] >> w[i] ;//输入背包内所有东西的体积和价值
  13. for (int i = 1; i <= n; i++) // 物品数量<n
  14. for (int j = 0; j <= m; j++) // 背包
  15. {
  16. // 当前背包容量装不下第 i 个物品, 则价值等于前 i-1 个物品
  17. f[i][j] = f[i - 1][j];
  18. // 当前背包容量能装下第 i 个物品, 选择是否装第 i 个物品, 取较大的那个结果
  19. if (j >= v[i]) f[i][j] = max(f[i - 1][j], f[i - 1][j - v[i]] + w[i]);
  20. }
  21. cout << f[n][m] << endl;
  22. return 0;
  23. }

c++ 一维数组做法:

  1. #include <iostream>
  2. #include <algorithm>
  3. using namespace std;
  4. //01背包 一维数组做法
  5. const int N = 1010;
  6. int n, m; // 物品数量, 背包容量
  7. int v[N], w[N]; // 体积 价值
  8. int f[N]; // 最大价值
  9. int main()
  10. {
  11. cin >> m >> n;// 输入物品数量, 背包容量
  12. for (int i = 1; i <= n; i++) cin >> v[i] >> w[i];//输入背包内所有东西的体积和价值
  13. for (int i = 1; i <= n; i++) // 物品数量<n
  14. for (int j = m; j >= v[i]; j--) // 背包
  15. f[j] = max(f[j], f[j - v[i]] + w[i]);//max(f[i - 1][j], f[i - 1][j - v[i]] + w[i]);
  16. cout << f[m] << endl;
  17. return 0;
  18. }

35 预定酒店

java

  1. import java.util.*;
  2. import java.util.stream.Stream;
  3. public class Main {
  4. public static void main(String[] args) {
  5. Scanner sc = new Scanner(System.in);
  6. String[] strs = sc.nextLine().split(" ");
  7. int n = Integer.parseInt(strs[0]);
  8. int k = Integer.parseInt(strs[1]);
  9. int x = Integer.parseInt(strs[2]);
  10. Integer[] integers =
  11. Arrays.stream(sc.nextLine().split(" ")).map(Integer::parseInt).toArray(Integer[]::new);
  12. ArrayList<int[]> list = new ArrayList<>();
  13. for(int i = 0; i < n; i ++ ) {
  14. Integer price = integers[i];
  15. int[] ints = new int[2];
  16. ints[0] = price;
  17. ints[1] = Math.abs(x - price);//距离价格的绝对值
  18. list.add(ints);
  19. }
  20. //排序 按照绝对值 和 价格大小
  21. list.sort(((o1, o2) -> {
  22. if (o1[1] == o2[1]) {//比较二者
  23. return o1[0] - o2[0];//如果绝对值相同 比比较数字大小 取较小的
  24. } else {
  25. return o1[1] - o2[1];//如果绝对值不同, 先按绝对值比较, 取绝对值小的
  26. }
  27. }));
  28. //把前k个结果保存到结果数组
  29. ArrayList<Integer> res = new ArrayList<>();
  30. //输出前k个
  31. for(int i = 0; i < k; i ++ ) {
  32. int i1 = list.get(i)[0];
  33. res.add(i1);
  34. }
  35. //按照值排序
  36. Collections.sort(res);
  37. for(int i = 0; i < k; i ++ ) {
  38. System.out.print(res.get(i));
  39. if(i != k - 1) System.out.print(" ");
  40. }
  41. // 参考答案中去除最后一个空格的方法:
  42. // StringBuilder sb = new StringBuilder();
  43. // for (int i = 0; i < res.size(); i++) {
  44. // sb.append(res.get(i)).append(" ");
  45. // }
  46. //
  47. // System.out.println(sb.deleteCharAt(sb.length()-1));
  48. }
  49. }

36 学校的位置

给学生家排序, 如果个数是奇数, 就在中间位置的学生家

如果是偶数, 就在中间两个位置的学生家之间, 题意要求输出较小的位置, 就是中间两个位置中靠左的那一个

这个用c++写更简单, java的话位移要加括号, 否则会报错

  1. import java.util.*;
  2. //学校的位置
  3. public class Main {
  4. public static void main(String[] args) {
  5. Scanner sc = new Scanner(System.in);
  6. int n = sc.nextInt();
  7. int[] sites = new int[n];
  8. for(int i = 0; i < n; i ++ ) {
  9. sites[i] = sc.nextInt();//存储家庭的位置
  10. }
  11. //排序
  12. Arrays.sort(sites);
  13. int res;
  14. if(n % 2 == 0) {
  15. res = sites[(n >> 1) - 1];
  16. } else {
  17. res = sites[(n - 1) >> 1];
  18. }
  19. System.out.println(res);
  20. }
  21. }

37 寻找密码

  1. import java.util.*;
  2. //37 寻找密码
  3. public class Main {
  4. public static void main(String[] args) {
  5. Scanner sc = new Scanner(System.in);
  6. String[] strings = sc.nextLine().split(" ");
  7. HashSet<String> set = new HashSet<>();
  8. set.addAll(Arrays.asList(strings));
  9. String str = "";//结果字符串
  10. for (String string : strings) {
  11. if (check(set, string)) {
  12. if (string.length() > str.length()) {
  13. str = string;
  14. }
  15. if (string.length() == str.length() && string.compareTo(str) > 0) {
  16. str = string;
  17. }
  18. }
  19. }
  20. System.out.println(str);
  21. }
  22. public static boolean check(Set<String> set, String str) {
  23. String tmp = str;
  24. boolean flag = true;
  25. //最大的密码就是 str str缩短 查询set的子集就好了
  26. for(int i = str.length() - 1; i > 0; i -- ) {
  27. tmp = str.substring(0, i);
  28. if(!set.contains(tmp)) flag = false;
  29. }
  30. return flag;
  31. }
  32. }

38 寻找关键钥匙

  1. import java.util.*;
  2. //38 寻找关键钥匙
  3. public class Main {
  4. public static void main(String[] args) {
  5. Scanner sc = new Scanner(System.in);
  6. String key = sc.nextLine();
  7. String[] boxes = sc.nextLine().split(" ");
  8. for(int i = 0; i < boxes.length; i ++ ) {
  9. String str = "";//保存待比较的字符串
  10. for(int j = 0; j < boxes[i].length(); j ++ ) {
  11. char c = boxes[i].charAt(j);
  12. c = Character.toLowerCase(c);
  13. if(c >= 'a' && c <= 'z') str += c;
  14. }
  15. //str = str.toLowerCase();//或者这么写 字符串转换
  16. char[] chars = str.toCharArray();//每个box转成 char数组
  17. Arrays.sort(chars);
  18. if(String.valueOf(chars).equals(key)) {
  19. System.out.println(i + 1);
  20. return;
  21. }
  22. }
  23. System.out.println("-1");
  24. }
  25. }

39 查找充电设备组合 TODO

java

  1. import java.util.*;
  2. //39 查找充电设备组合
  3. public class Main {
  4. public static void main(String[] args) {
  5. Scanner sc = new Scanner(System.in);
  6. int n = sc.nextInt();
  7. ArrayList<Integer> list = new ArrayList<>();//存储充电设备的集合
  8. for(int i = 0; i < n; i ++ ) {
  9. list.add(sc.nextInt());
  10. }
  11. int p_max = sc.nextInt();//最大功率
  12. int max = 0;//结果数组里的最大功率
  13. HashSet<Integer> res = new HashSet<>();
  14. res.add(0);//存一个0
  15. for(Integer num : list){
  16. HashSet<Integer> tmps = new HashSet<>();//每一次遍历的临时数组
  17. for(Integer power : res) {//循环一遍每个结果
  18. int new_p = power + num;
  19. if(new_p <= p_max) {
  20. tmps.add(new_p);//做临时数组来存, 否则会改变遍历的情况
  21. max = Math.max(new_p, max);
  22. }
  23. }
  24. res.addAll(tmps);
  25. }
  26. System.out.println(max);
  27. }
  28. }

40 知识图谱新词挖掘

  1. import java.util.*;
  2. //39 查找充电设备组合
  3. public class Main {
  4. public static void main(String[] args) {
  5. Scanner sc = new Scanner(System.in);
  6. String content = sc.nextLine();
  7. String word = sc.nextLine();
  8. int len_c = content.length();
  9. int len_w = word.length();
  10. char[] words = word.toCharArray();
  11. Arrays.sort(words);//排序后
  12. int count = 0;
  13. for(int i = 0; i < len_c - len_w + 1; i ++ ) {
  14. String new_word = content.substring(i, len_w + i);
  15. char[] new_words = new_word.toCharArray();
  16. Arrays.sort(new_words);
  17. if(String.valueOf(new_words).equals(String.valueOf(words))) {
  18. count ++;
  19. }
  20. }
  21. System.out.println(count);
  22. }
  23. }

41 静态代码扫描服务

java

记得换行的时候要 sc.NextLine(); !!!!!

  1. import java.util.*;
  2. //39 查找充电设备组合
  3. public class Main {
  4. public static void main(String[] args) {
  5. Scanner sc = new Scanner(System.in);
  6. int m = sc.nextInt();//缓存一个报告的金币数m
  7. sc.nextLine();//换行了!!!!!
  8. String[] nums = sc.nextLine().split(" ");//标识序列
  9. String[] sizes = sc.nextLine().split(" ");//每个文件的大小
  10. HashMap<Integer, Integer> numsMap = new HashMap<>();//存储 标识 - 个数
  11. HashMap<Integer, Integer> sizeMap = new HashMap<>();//存储 标识 - 大小
  12. //把两个map存好
  13. for(int i = 0; i < nums.length; i ++ ) {
  14. int num = Integer.parseInt(nums[i]);
  15. int size = Integer.parseInt(sizes[i]);
  16. if(numsMap.containsKey(num)) {
  17. numsMap.put(num, numsMap.get(num) + 1);
  18. } else {
  19. numsMap.put(num, 1);
  20. sizeMap.put(num, size);
  21. }
  22. }
  23. int res = 0;
  24. for(Map.Entry<Integer, Integer> map : numsMap.entrySet()) {
  25. Integer key = map.getKey();//标识
  26. Integer value = map.getValue();//文件个数
  27. Integer size = sizeMap.get(key);//文件大小(扫描一次的成本价格)
  28. int save = 0;
  29. int noSave = 0;//每个标识文件 的 存和不存的需要金币数
  30. save = m + size;//缓存一个报告的金币数m + 扫描的成本(文件大小)
  31. noSave = value * size;//不缓存, 每次都扫描, 大小 * 个数
  32. res += Math.min(save, noSave);
  33. }
  34. System.out.println(res);
  35. }
  36. }

42 不爱施肥的小布

java: 

这个向上取整没整明白 ceil为啥没取到呢, 换了朴素写法

  1. import java.util.*;
  2. //42
  3. public class Main {
  4. public static void main(String[] args) {
  5. Scanner sc = new Scanner(System.in);
  6. int m = sc.nextInt();//m个果林
  7. int n = sc.nextInt();//n天
  8. int[] fields = new int[m];
  9. for(int i = 0; i < m; i ++ ) {
  10. fields[i] = sc.nextInt();
  11. }
  12. Arrays.sort(fields);
  13. int k = 0;
  14. int cnt = 0;
  15. int res = 0;
  16. for(int i = 0; i < m; i ++ ) {
  17. k = fields[i];
  18. cnt += i + 1;//前i个都可以1天完成
  19. for(int j = i + 1; j < m; j ++ ) {
  20. int days = fields[j] / k;
  21. if(fields[j] % k != 0) {
  22. days ++ ;
  23. }
  24. // int days = (int) Math.ceil(fields[j] / k);//向上取整
  25. cnt += days;
  26. }
  27. if(cnt <= n) {
  28. System.out.println(k);
  29. return;
  30. }
  31. cnt = 0;
  32. }
  33. System.out.println("-1");
  34. }
  35. }

44 新员工座位安排系统

我写的

  1. import java.util.*;
  2. //44 新员工座位安排
  3. public class Main {
  4. public static void main(String[] args) {
  5. Scanner sc = new Scanner(System.in);
  6. String[] strings = sc.nextLine().split(" ");
  7. int n = strings.length;
  8. int[] a = new int[n];
  9. boolean flag = false;
  10. ArrayList<Integer> indexes = new ArrayList<>();
  11. for(int i = 0; i < n; i ++ ) {
  12. a[i] = Integer.parseInt(strings[i]);
  13. if(a[i] == 0) {
  14. flag = true;//只要有0 就改为true
  15. indexes.add(i);//存入0点的下标
  16. }
  17. }
  18. if(!flag) {
  19. System.out.println(0);
  20. return;
  21. }
  22. int res = 0;
  23. int tmp = 0;//当前的友好值
  24. //0点所在的下标
  25. for (Integer index : indexes) {//枚举每个0点
  26. if (index != 0) {
  27. int l = index - 1;
  28. while (a[l] == 1) {
  29. tmp++;
  30. if (l == 0) break;
  31. l--;
  32. }
  33. }
  34. if (index != n - 1) {
  35. int r = index + 1;
  36. while (a[r] == 1) {
  37. tmp++;
  38. if (r == n - 1) break;
  39. r++;
  40. }
  41. }
  42. res = Math.max(res, tmp);
  43. tmp = 0;
  44. }
  45. System.out.println(res);
  46. }
  47. }

45 光伏场地建设规划

java

  1. import java.util.Scanner;
  2. //45 光伏场地建设规划
  3. public class Main {
  4. public static void main(String[] args) {
  5. Scanner sc = new Scanner(System.in);
  6. String[] strings = sc.nextLine().split(" ");
  7. int row = Integer.parseInt(strings[0]);
  8. int col = Integer.parseInt(strings[1]);
  9. int n = Integer.parseInt(strings[2]);
  10. int min = Integer.parseInt(strings[3]);//最低发电量
  11. int[][] a = new int[row][col];
  12. for(int i = 0; i < row; i ++ ) {
  13. for(int j = 0; j < col; j ++ ) {
  14. a[i][j] = sc.nextInt();
  15. }
  16. }
  17. if(col < n || row < n) {
  18. System.out.println("0");
  19. return;
  20. }
  21. int[][] area = new int[n][n];
  22. int sum = 0;
  23. int res = 0;
  24. for(int k = 0; k < row - n + 1; k ++ ) {
  25. for(int p = 0; p < col - n + 1; p ++ ) {//遍历所有起始点的位置
  26. for (int i = 0; i < n; i++) {//正方形内的值
  27. for (int j = 0; j < n; j++) {
  28. area[i][j] = a[i + k][j + p];//相对地址 +k +p
  29. sum += area[i][j];
  30. }
  31. }
  32. if(sum >= min) res ++;
  33. sum = 0;
  34. }
  35. }
  36. System.out.println(res);
  37. }
  38. }

java

  1. import java.util.Scanner;
  2. //45 光伏场地建设规划
  3. public class Main {
  4. public static void main(String[] args) {
  5. Scanner sc = new Scanner(System.in);
  6. String[] strings = sc.nextLine().split(" ");
  7. int row = Integer.parseInt(strings[0]);
  8. int col = Integer.parseInt(strings[1]);
  9. int n = Integer.parseInt(strings[2]);
  10. int min = Integer.parseInt(strings[3]);//最低发电量
  11. int[][] a = new int[row][col];
  12. for(int i = 0; i < row; i ++ ) {
  13. for(int j = 0; j < col; j ++ ) {
  14. a[i][j] = sc.nextInt();
  15. }
  16. }
  17. if(col < n || row < n) {
  18. System.out.println("0");
  19. return;
  20. }
  21. int count = (col - n + 1) * (row - n + 1);//总数是这些
  22. int[][] area = new int[n][n];
  23. int sum = 0;
  24. for(int k = 0; k < row - n + 1; k ++ ) {
  25. for(int p = 0; p < col - n + 1; p ++ ) {
  26. for (int i = 0; i < n; i++) {
  27. for (int j = 0; j < n; j++) {
  28. area[i][j] = a[i + k][j + p];
  29. sum += area[i][j];
  30. }
  31. }
  32. if(sum < min) count --;//不满足的减掉
  33. sum = 0;
  34. }
  35. }
  36. System.out.println(count);
  37. }
  38. }

46 微服务的集成测试 dfs

java

  1. import java.util.*;
  2. //微服务的集成测试
  3. public class Main {
  4. public static void main(String[] args) {
  5. Scanner sc = new Scanner(System.in);
  6. int n = sc.nextInt();
  7. int[][] useTime = new int[n][n];
  8. for(int i = 0; i < n; i ++ ) {
  9. for(int j = 0; j < n; j ++ ) {
  10. useTime[i][j] = sc.nextInt();
  11. }
  12. }
  13. int k = sc.nextInt();//待计算 的 服务 k
  14. int cnt = 0;
  15. cnt = dfs(useTime, k - 1);
  16. System.out.println(cnt);
  17. }
  18. public static int dfs(int[][] useTime, int k) {
  19. int max = 0;
  20. // 计算启动服务k的时间
  21. //遍历k的一行数据, 得到它依赖的服务器, 获得启动时间
  22. for(int j = 0; j < useTime.length; j ++ ) {
  23. int tmp = useTime[k][j];
  24. if(tmp != 0 && j != k ) {
  25. max = Math.max(max, dfs(useTime, j));
  26. }
  27. }
  28. return max + useTime[k][k];//依赖的加载时间 max + 自身的加载时间
  29. }
  30. }

47 字符串重新排序

java

  1. import java.util.*;
  2. //微服务的集成测试
  3. public class Main {
  4. public static void main(String[] args) {
  5. Scanner sc = new Scanner(System.in);
  6. String[] strings = sc.nextLine().split(" ");
  7. HashMap<String, Integer> map = new HashMap<>();
  8. for(int i = 0; i < strings.length; i ++ ) {
  9. String key = arrange(strings[i]);//单词字典序
  10. map.put(key, map.getOrDefault(key, 0) + 1);//map存储 单词和出现次数
  11. }
  12. ArrayList<Map.Entry<String, Integer>> list = new ArrayList<>(map.entrySet());
  13. list.sort(new Comparator<Map.Entry<String, Integer>>() {
  14. @Override
  15. public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
  16. if(o2.getValue() == o1.getValue()) {//出现次数相同的情况下, 按照单词(key)的长度排序
  17. if(o1.getKey().length() == o2.getKey().length()) {
  18. return o1.getKey().compareTo(o2.getKey());//单词长度相同, 按照字典序升序
  19. }
  20. return o1.getKey().length() - o2.getKey().length();//按照单词长度升序排
  21. }
  22. return o2.getValue() - o1.getValue();//按照出现次数降序排
  23. }
  24. });
  25. for(int i = 0; i < list.size(); i ++ ) {
  26. for(int j = 0; j < list.get(i).getValue(); j ++ ) {
  27. System.out.print(list.get(i).getKey());
  28. if (i != list.size() - 1) System.out.print(" ");
  29. }
  30. }
  31. }
  32. public static String arrange(String str) {//单词内部的字典序
  33. //list可以排字典序
  34. ArrayList<Character> list = new ArrayList<>();
  35. for(int i = 0; i < str.length(); i ++ ) {
  36. list.add(str.charAt(i));
  37. }
  38. list.sort(new Comparator<Character>() {
  39. @Override
  40. public int compare(Character o1, Character o2) {
  41. return o1.compareTo(o2);
  42. }
  43. });
  44. StringBuilder res = new StringBuilder();
  45. for(char c : list) {
  46. res.append(c);
  47. }
  48. return res.toString();
  49. }
  50. }

48 MVP争夺战 TODO 要背

这个有点难, dfs

java

  1. import java.util.*;
  2. //48 MVP争夺战
  3. public class Main {
  4. static int max = -1;
  5. static int min = 51;
  6. static int[] cnt = new int[51];
  7. public static void main(String[] args) {
  8. Scanner sc = new Scanner(System.in);
  9. int t = sc.nextInt();//有得分的分钟数 [1,50]
  10. int[] scores = new int[t];
  11. int sum = 0;
  12. for(int i = 0; i < t; i ++ ) {
  13. scores[i] = sc.nextInt();
  14. sum += scores[i];
  15. cnt[scores[i]] ++ ;//得分i 出现几次cnt[i]
  16. }
  17. Arrays.sort(scores);
  18. max = scores[t - 1];//最末尾就是最大值
  19. min = scores[0];//最开头就是最大值
  20. //mvp得分即是 = 总分 / 人数 = 平均分
  21. //最小平均分 数组的最大值
  22. //最大平均分 总分, 即所有都是一个人投中的
  23. // [数组里的最大值, sum / 1]
  24. //按照题意 找最小平均分, 从最小平均分开始遍历, 满足条件则结束
  25. for(int i = max; i <= sum; i ++ ) {
  26. if(sum % i == 0) {//mvp平均分 能被 总分 整除 = mvp人数, 才有意义
  27. dfs(sum / i, 0, i, max);//dfs(总人数, 当前的分数和0, 目标平均分. 枚举位置?)
  28. }
  29. }
  30. System.out.println(sum);
  31. }
  32. public static void dfs(int res, int sum, int target, int p) {
  33. //人数是0了 说明所有人都被遍历过了, 输出结果
  34. if(res == 0) {//表示一种情况结束了
  35. System.out.println(target);
  36. System.exit(0);
  37. }
  38. //当 一个获得的分数sum == 目标平均分target, 遍历其余人
  39. if(sum == target) {
  40. dfs(res - 1, 0, target, max);//下一个
  41. // dfs(人-1, 该人的分0, 目标分target, 继续从最大开始枚举)
  42. return;
  43. }
  44. //i从 最大得分 遍历到 最小得分, 枚举每个数字 选择是否用
  45. for(int i = p; i >= min; -- i) {
  46. //如果这个分数是在原数组中存在的 cnt>0 且加上之后 <= 目标分, 就把该数字用掉
  47. if(cnt[i] > 0 && (i + sum) <= target) {
  48. cnt[i] --;//用到该数字 i
  49. dfs(res, sum + i, target, i);//dfs(还是当前人, 当前人的分数, 目标分, 继续从i枚举);
  50. cnt[i] ++ ;//放回该数字
  51. if(sum == 0 || (sum + i) == target) {
  52. break;
  53. }
  54. }
  55. }
  56. }
  57. }

49 贪心的商人

java

  1. import java.util.*;
  2. //49 贪心的商人
  3. public class Main {
  4. public static void main(String[] args) {
  5. Scanner sc = new Scanner(System.in);
  6. int number = sc.nextInt();//商品种类
  7. int days = sc.nextInt();//天数
  8. int[] v = new int[number];
  9. for(int i = 0; i < number; i ++ ) {
  10. v[i] = sc.nextInt();//商品i的最大持有量 v[i]
  11. }
  12. int[][] w = new int[number][days];//第i个商品 的 第j天的价格
  13. for(int i = 0; i < number; i ++ ) {
  14. for(int j = 0; j < days; j ++ ) {
  15. w[i][j] = sc.nextInt();//
  16. }
  17. }
  18. int tmp = 0;
  19. int res = 0;
  20. for(int i = 0; i < number; i ++ ) {
  21. for(int j = 0; j < days - 1; j ++ ) {
  22. for(int k = j; k < days; k ++ ) {
  23. int sell = w[i][k];
  24. int buy = w[i][j];
  25. tmp = Math.max((sell - buy) * v[i], tmp);//每个商品的最大利润
  26. }
  27. }
  28. res += tmp;
  29. tmp = 0;//换商品的时候置0
  30. }
  31. System.out.println(res);
  32. }
  33. }

50 核酸检测人员安排

java

这也用不到dp 数学退一下就行了

  1. import java.util.*;
  2. //50 核酸检测人员安排
  3. public class Main {
  4. public static void main(String[] args) {
  5. Scanner sc = new Scanner(System.in);
  6. int c_num = sc.nextInt();//采样员
  7. int z_num = sc.nextInt();//志愿者
  8. int[] k = new int[c_num];
  9. int sum = 0;
  10. for(int i = 0; i < c_num; i ++ ) {
  11. k[i] = sc.nextInt();//每个员工的效率
  12. sum += k[i];
  13. }
  14. Arrays.sort(k);//从小到大 按照效率排序
  15. int res = 0;
  16. //每个都要保证 1个
  17. if(z_num <= c_num) {//志愿者不足 1倍的采样员
  18. //从尾到头遍历 基准效率 60-600 m= 6-60
  19. // 所以分配给个人更好 不需要判断 M > k[i]的情况
  20. for(int i = c_num - 1; i > c_num - z_num - 1; i -- ) {
  21. res += k[i];
  22. }
  23. } //每个保证1个
  24. else if(z_num < c_num * 3) {//志愿者1-3倍 采样员
  25. int left = z_num - c_num;
  26. res = sum;
  27. for(int i = c_num - 1; i > 0; i -- ) {
  28. int m = (int) (k[i] * 0.1);
  29. if(left >= 3) {
  30. res += 3 * m;
  31. left -= 3;
  32. } else {
  33. res += left * m;
  34. left = 0;
  35. }
  36. }
  37. } else { //志愿者>= 3倍采样员的时候
  38. res = (int) (sum * 1.3);
  39. }
  40. System.out.println(res);
  41. }
  42. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/174233
推荐阅读
相关标签
  

闽ICP备14008679号