第二道:三个数组abc,游游打算重排c数组,使得尽可能多的下标i满足ai+bi=ci。思路:ai+bi的值是固定的 先用一个for循环算一遍 放到map里 ,key是值,value是个数,然后再用一个for循环 看看数组c里的值有没有在map里出现,有的话 计数+1,并且让map里相应的key 值-1 然后就好了。第三题:给一个数组,每次操作可以把相邻的两个素数元素进行合并,合并后的新数为原来的两个数之和,并删除原来两个数。现在希望最终数组的元素数量尽可能少。第一行输入n表示数组大小,第二行输入n个正整数,表示数组元素。思路:1.写一个检查是否是素数的函数2.写一个合并函数:2.1先判断2 这个特殊情况 因为素数2和相邻的素数合并 结果可能是素数也可能是非素数 别的素数合并都是非素数。所以要先判断存不存在2和相邻的一边的素数合并是素数 另一边合并不是素数的情况 比如数组7 2 3 后两个先合并和前两个先合并就不一样。2.2再把其余素数合并代码:import java.util.ArrayList;  import java.util.List;  import java.util.Scanner;    public class PrimeMerge {      public static void main(String[] args) {          Scanner scanner = new Scanner(System.in);          int n = scanner.nextInt();          List<Integer> numbers = new ArrayList<>();            // 读取数组元素          for (int i = 0; i < n; i++) {              numbers.add(scanner.nextInt());          }            // 关闭Scanner          scanner.close();            // 合并素数,优先处理2          mergePrimesWithPriorityToTwo(numbers);            // 输出最终数组          for (int num : numbers) {              System.out.print(num + " ");          }      }        private static void mergePrimesWithPriorityToTwo(List<Integer> numbers) {          // 检查一个数是否是素数的辅助函数          boolean isPrime(int num) {              if (num <= 1) return false;              for (int i = 2; i * i <= num; i++) {                  if (num % i == 0) {                      return false;                  }              }              return true;          }            // 合并2与其相邻的素数          for (int i = 0; i < numbers.size(); ) {              if (numbers.get(i) == 2) {                  // 检查左边是否有素数可以合并                  if (i > 0 && isPrime(numbers.get(i - 1)) && isPrime(numbers.get(i - 1) + 2)) {                      numbers.set(i - 1, numbers.get(i - 1) + 2);                      numbers.remove(i);                  } else if (i < numbers.size() - 1 && isPrime(numbers.get(i + 1)) && isPrime(numbers.get(i + 1) + 2)) {                      // 检查右边是否有素数可以合并                      numbers.set(i, numbers.get(i) + numbers.get(i + 1));                      numbers.remove(i + 1);                  } else {                      // 没有可以合并的素数,继续下一个数                      i++;                  }              } else {                  i++;              }          }            // 合并剩余的素数对          for (int i = 0; i < numbers.size() - 1; ) {              if (isPrime(numbers.get(i)) && isPrime(numbers.get(i + 1)))) {                  numbers.set(i, numbers.get(i) + numbers.get(i + 1));                  numbers.remove(i + 1);              } else {                  i++;              }          }      }  }第四题:定义一棵树的直径为:任意两个节点的距离的最大值。现在定义f(i):对i号节点上再连接一个新的子叶节点后,树的直径长度。现在要求f(1)到f(n)的值。输入描述:第一行输入一个正整数n,代表树的节点数量。接下来的n-1行,每行输入两个正整数u和v,代表u号节点和v号节点之间有一条长度为1的边连接。变量的范围:1≤n≤10的五次方,1≤u,v≤n。思路:第四题说是树的直径,但其实就是图,但是可以用二叉树类比着来做。1.写一个树类,val表示节点编号,children表示孩子链表。把每个节点创建处理并保存,把每个节点的孩子节点添加一下。2.写一个for循环,针对每个f(i),把新的子叶节点添加一下,然后调用dfs处理得到f(i)值。3.dfs:二叉树求直径实际上是求子树的深度,然后左右子树深度相加就是直径,返回结果是左右子树深度的最大值+1。同样的道理,这里也是求所有子树的深度,记录最大深度和第二大深度,然后f(i)就是最大深度和第二大深度之和,返回结果就是最大深度+1。代码:import java.util.*;class TreeNode {    int val;    List<TreeNode> children;        public TreeNode(int val) {        this.val = val;        children = new ArrayList<>();    }}public class TreeDiameter {    public static int[] f; // 存储每个节点的f(i)值        public static void main(String[] args) {        Scanner scanner = new Scanner(System.in);        int n = scanner.nextInt(); // 树的节点数量                f = new int[n + 1]; // 初始化f数组                // 构建树的数据结构        TreeNode[] nodes = new TreeNode[n + 1];        for (int i = 1; i <= n; i++) {            nodes[i] = new TreeNode(i);        }                // 连接节点之间的关系        for (int i = 0; i < n - 1; i++) {            int u = scanner.nextInt();            int v = scanner.nextInt();            nodes[u].children.add(nodes[v]);            nodes[v].children.add(nodes[u]);        }                // 遍历每个节点,添加一个新的子叶节点,计算f(i)        for (int i = 1; i <= n; i++) {            // 添加新的子叶节点            addLeafAndDFS(nodes[i], n + i);            // 计算f(i)            dfs(nodes[i], null, i);        }                // 输出结果        for (int i = 1; i <= n; i++) {            System.out.print(f[i] + " ");        }    }        // 添加新的子叶节点,并调用dfs计算f(i)    public static void addLeafAndDFS(TreeNode node, int newLeafValue) {        TreeNode newLeaf = new TreeNode(newLeafValue); // 创建新的子叶节点        node.children.add(newLeaf); // 添加到当前节点的子节点中        newLeaf.children.add(node); // 添加当前节点作为新的子叶节点的父节点    }        // 递归计算以当前节点为根的子树的直径    public static void dfs(TreeNode node, TreeNode parent, int i) {        int maxDepth1 = 0; // 最大深度        int maxDepth2 = 0; // 次大深度                // 遍历当前节点的子节点        for (TreeNode child : node.children) {            if (child == parent) continue; // 避免回溯            int childDepth = dfs(child, node, i); // 递归计算子节点的深度            if (childDepth > maxDepth1) {                maxDepth2 = maxDepth1;                maxDepth1 = childDepth;            } else if (childDepth > maxDepth2) {                maxDepth2 = childDepth;            }        }                // 更新f(i)        f[i] = Math.max(f[i], maxDepth1 + maxDepth2);    }}
点赞 7
评论 7
全部评论

相关推荐

不愿透露姓名的神秘牛友
07-31 17:23
点赞 评论 收藏
分享
Java大菜狗:纯纯招黑奴,一天还不到两百那么多要求,还不迟到早退,以为啥啊,给一点工资做一堆活,还以不拖欠员工工资为荣,这是什么值得骄傲的事情吗,纯纯***公司
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务