hwod机考练习

文章讲述了作者在编程挑战中遇到的四个问题,涉及字符串中整数的最小和计算、满足条件的最长子串长度、字符串分割和动态规划解决玩牌高手问题。展示了使用BigInteger处理大整数和数据结构如栈、队列和并查集的实践应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

不一定正确,都是自己凭感觉写的辣鸡代码

Day 1

题目详情 - 求字符串中所有整数的最小和 - Hydro

评测结果两个运行时错误,别的用例都过了,看不到用例详情不知道哪里写错了,先不管了就这样吧

估计是因为没用BigInteger,题目没说数字范围

public class Main {
  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    getResult(scanner.nextLine());
  }

  static void getResult(String s) {
    // int res = 0;
    BigInteger res = new BigInteger("0");
    char[] chars = s.toCharArray();
    int i = 0;
    while (i < chars.length) {
      char c = chars[i];
      if (isNum(c)) {
        int j = i;
        for (; j < chars.length && isNum(chars[j]); j++) {
          // res += Integer.parseInt(String.valueOf(chars[j]));
          // 用BigInteger!!
          res = res.add(new BigInteger(String.valueOf(chars[j])));
        }
        i = j;
        continue;
      }
      if (c == '-') {
        int j = i + 1;
        if (j > chars.length - 1) break;
        for (; j < chars.length && isNum(chars[j]); j++) {}
        if (j > i + 1) {
          String subString = s.substring(i + 1, j);
          // int numberToDecrease = Integer.parseInt(subString);
          // res -= numberToDecrease;
          // 用BigInteger!!
          res = res.subtract(new BigInteger(subString));
          i = j;
        } else i++;
        continue;
      }
      i++;
    }
    System.out.println(res);
  }

  static boolean isNum(char c) {
    return c >= '0' && c <= '9';
  }
}

Day 2

题目详情 - 求满足条件的最长子串的长度 - Hydro

public class Main {
  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    getResult(scanner.nextLine());
  }

  static void getResult(String input) {
    char[] chars = input.toCharArray();
    int length = 0;
    for (int i = 0; i < chars.length; i++) {
      char c = chars[i];
      if (isNum(c)) {
        int letterCount = 0;
        int j = i;
        for (; j < chars.length; j++) {
          if (!isNum(chars[j])) letterCount++;
          if (letterCount > 1) break;
        }
        if (j > i) {
          if (letterCount > 0) length = Math.max(length, j - i);
          else if (i > 0 && !isNum(chars[i - 1])) length = Math.max(length, j - i + 1);
        }
      }
    }
    System.out.println(length == 0 ? -1 : length);
  }

  static boolean isNum(char c) {
    return c >= '0' && c <= '9';
  }
}

Day 3

题目详情 - 字符串分割(二) - Hydro

其实可以滑动窗口,自己只想到了暴力解

public class Main {
  static final int CHAR_OFFSET = 'a' - 'A';

  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    int k = scanner.nextInt();
    String input = scanner.next();
    scanner.close();

    String[] split = input.split("-");
    StringBuilder sb = new StringBuilder();
    StringBuilder head = new StringBuilder(split[0]);
    for (int i = 1; i < split.length; i++) {
      sb.append(split[i]);
    }
    int count = 0;
    for (int i = 0, j = 0; i < sb.length(); i++) {
      count++;
      if (count == k) {
        transform(sb, j, i + 1);
        if (i < sb.length() - 1) sb.insert(++i, '-');
        j = i;
        count = 0;
      } else if (i == sb.length() - 1) {
        transform(sb, j, i + 1);
      }
    }
    if (sb.length() > 0) head.append('-').append(sb);
    System.out.println(head);
  }

  static void transform(StringBuilder sb, int start, int end) {
    int upperCount = 0, lowerCount = 0;
    ArrayList<Integer> upperIndices = new ArrayList<>();
    ArrayList<Integer> lowerIndices = new ArrayList<>();
    for (int i = start; i < end; i++) {
      char c = sb.charAt(i);
      if (c >= 'A' && c <= 'Z') { // uppercase
         upperCount++;
         upperIndices.add(i);
      }
      if (c >= 'a' && c <= 'z') { // lowercase
        lowerCount++;
        lowerIndices.add(i);
      }
    }
    if (upperCount > lowerCount) {
      lowerIndices.forEach(i -> sb.setCharAt(i, (char) (sb.charAt(i) - CHAR_OFFSET)));
    }
    if (upperCount < lowerCount) {
      upperIndices.forEach(i -> sb.setCharAt(i, (char) (sb.charAt(i) + CHAR_OFFSET)));
    }
  }
}

题目详情 - 玩牌高手 - Hydro

动态规划

public class Main {
  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    getResult(scanner.nextLine());
    scanner.close();
  }

  static void getResult(String input) {
    String[] nums = input.split(",");
    int[] max = new int[nums.length];
    max[0] = Math.max(Integer.valueOf(nums[0]), 0);
    for (int i = 1; i < nums.length; i++) {
      max[i] = Math.max(max[i - 1] + Integer.valueOf(nums[i]), i <= 2 ? 0 : max[i - 3]);
    }
    System.out.println(max[max.length - 1]);
  }
}

题目详情 - 欢乐的周末 - Hydro

public class Main {
  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    int height = scanner.nextInt();
    int width = scanner.nextInt();
    // 填充矩阵
    int[][] matrix = new int[height][width];
    for (int i = 0; i < height; i++) {
      for (int j = 0; j < width; j++) {
        matrix[i][j] = scanner.nextInt();
      }
    }
    scanner.close();
    
    // 用于便捷计算任意一点朝上/下/左/右移动后的坐标
    int[][] offsets = { {0, 1}, {1, 0}, {-1, 0}, {0, -1} };
    // 华为二人所在坐标
    List<Integer> huawei = new ArrayList<>();
    // 馆子坐标
    List<Integer> joints = new ArrayList<>();
    // 并查集,里面放矩阵中各点的坐标的整数表示
    UnionFind unionFind = new UnionFind(width * height);
   
    // 遍历矩阵 
    for (int i = 0; i < matrix.length; i++) {
      for (int j = 0; j < matrix[i].length; j++) {
        int n = matrix[i][j];
        if (n == 1) continue; // 遇到障碍物跳过
        int pos = j + i * width; // 二维坐标转为一个整数,作为存在于并查集中的位置
        if (n == 2) huawei.add(pos);
        if (n == 3) joints.add(pos);
        // 对于矩阵中任意一点,检查它与它上下左右各点的连通性
        for (int[] offset : offsets) {
          int newI = i + offset[0];
          int newJ = j + offset[1];
          if (newI >= 0 && newJ >=0 && newI < matrix.length && newJ < matrix[newI].length) {
            // 若上/下/左/右点的坐标合法,且与原点连通(值不为1),就在并查集中将其与原点融合
            if (matrix[newI][newJ] != 1) {
              int newPos = newJ + newI * width;
              unionFind.union(newPos, pos);
            }
          }
        }
      }
    }

    // 华为两人若不连通说明吃不到一块去,return
    if (!unionFind.isSameRoot(huawei.get(0), huawei.get(1))) {
      System.out.println(0);
      return;
    }

    int sum = 0;

    // 遍历馆子,如果馆子跟华为其中一人联通说明能吃饭,加一
    for (int pos : joints) {
      if (unionFind.isSameRoot(pos, huawei.get(0))) sum++;
    }

    System.out.println(sum);
  }

  static final class UnionFind {
    int[] arr;
    public UnionFind(int length) {
      arr = new int[length];
      for (int i = 0; i < length; i++) arr[i] = i;
    }

    public int findRoot(int e) {
      int root = arr[e];
      if (arr[root] != root) {
        arr[root] = findRoot(root);
        return arr[root];
      }
      return root;
    }

    public void union(int a, int b) {
      int rootA = findRoot(a);
      int rootB = findRoot(b);
      if (rootA != rootB) arr[rootA] = rootB;
    }

    public boolean isSameRoot(int a, int b) {
      return findRoot(a) == findRoot(b);
    }
  }
}

Day 4

题目详情 - 转盘寿司 - Hydro

public static void main(String[] args) {
  Scanner scanner = new Scanner(System.in);
  String line = scanner.nextLine();
  scanner.close();
  // 栈,存储{ 下标, 数值 }
  Deque<int[]> stack = new LinkedList<>();
  String[] split = line.split(" ");
  int leng = split.length;
  List<Integer> nums = Arrays.stream(split).map(Integer::valueOf).collect(Collectors.toList());
  // map存已经被处理过的数字,键是下标,值是处理后的数值
  Map<Integer, Integer> map = new HashMap<>();
  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < leng; j++) {
      int curr = nums.get(j);
      // 若当前值比栈顶值小,栈顶值出栈,并将值与当前值相加,存到map,循环这一过程直到栈顶值大于等于当前值或者栈空
      while (!stack.isEmpty() && curr < stack.peek()[1]) {
        // record: { index, value }
        int[] record = stack.pop();
        map.put(record[0], record[1] + curr);
      }
      // 已经被处理过的数字就不入栈了
      if (!map.containsKey(j)) stack.push(new int[]{ j, curr });
    }
  }
  map.forEach(nums::set);
  System.out.println(nums.stream().map(String::valueOf).collect(Collectors.joining(" ")));
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值