尺取法:PIPI的目标Ⅲ

深藏阁楼爱情的钟 2023-10-06 21:58 118阅读 0赞

尺取法:PIPI的目标Ⅲ

文章目录

  • 尺取法:PIPI的目标Ⅲ
      • 问题:
      • 思路:
      • 代码:

问题:

在这里插入图片描述
在这里插入图片描述

思路:

  首先对数组R进行排序,如果直接枚举a,b,c的话,时间复杂度为O(n^3),肯定会超时,那么我们接下来考虑使用尺取法来解决此题。
  我们只枚举a,然后令b=a+1,即b为a的下一位,c=n。枚举过程如下:
  如果此时R[a]+R[b]+R[c]==0,那么满足要求,我们输出结果,然后令b++,c- -,之后继续进行和的判断。
  如果此时R[a]+R[b]+R[c]<0,那么显然我们的值小了。由于我们枚举的是a,所以此时a不能动,那么只能动b或者c,而只有动b才能让它变大,所以让b++,之后继续进行和的判断。   如果此时R\[a\]+R\[b\]+R\[c\]>0,那么显然我们的值大了。a不能动,那么只能动b或者c,而只有动c才能让它变小,所以让c- -,之后继续进行和的判断。
  当b在c之后或b和c重叠时,则我们已经枚举完了当前a的所有情况,则a移到下一位,继续进行枚举判断过程

  题目要求我们输出不重复的答案,因此我们将< a, b, c >定义为三元组TriGroup,用一个HashSet来进行去重。需要注意的是,我们必须重写TriGroup的equals方法,因为我们这里的逻辑是当三元组中a,b,c的值对应相等,则认为两个TriGroup是同一个,而默认的equals方法是通过==判断实现的。hashCode方法也要重写,因为HashSet的add方法,调用的实际上是其内置的HashMap的put方法,该方法是要使用到键的hash值的,而计算hash值就是用的hashCode方法,因此我们重写hashCode方法,使其返回a,b,c共同决定的hash值

代码:

  1. import java.util.*;
  2. public class Main {
  3. static int[] array = new int[1005];
  4. static Set<TriGroup> set = new HashSet<>();
  5. public static void main(String[] args) {
  6. int a, b, c, n, i, aIndex, bIndex, cIndex;
  7. Scanner scanner = new Scanner(System.in);
  8. while (scanner.hasNextInt()) {
  9. set.clear();
  10. n = scanner.nextInt();
  11. for (i = 0; i < n; i++) {
  12. array[i] = scanner.nextInt();
  13. }
  14. Arrays.sort(array, 0, n);
  15. for (i = 0; i < n - 2; i++) {
  16. aIndex = i;
  17. bIndex = i + 1;
  18. cIndex = n - 1;
  19. a = array[aIndex];
  20. b = array[bIndex];
  21. c = array[cIndex];
  22. while (bIndex < cIndex) {
  23. if (a + b + c < 0) {
  24. bIndex++;
  25. b = array[bIndex];
  26. }
  27. if (a + b + c > 0) {
  28. cIndex--;
  29. c = array[cIndex];
  30. }
  31. if (a + b + c == 0 && cIndex > bIndex) {
  32. TriGroup triGroup = new TriGroup(a, b, c);
  33. if (!set.contains(triGroup)) {
  34. set.add(triGroup);
  35. System.out.println(a + " " + b + " " + c);
  36. }
  37. bIndex++;
  38. b = array[bIndex];
  39. cIndex--;
  40. c = array[cIndex];
  41. }
  42. }
  43. }
  44. }
  45. }
  46. }
  47. class TriGroup {
  48. public int a;
  49. public int b;
  50. public int c;
  51. public TriGroup(int a, int b, int c) {
  52. this.a = a;
  53. this.b = b;
  54. this.c = c;
  55. }
  56. @Override
  57. public boolean equals(Object o) {
  58. if (this == o) return true;
  59. if (o == null || getClass() != o.getClass()) return false;
  60. TriGroup triGroup = (TriGroup) o;
  61. return a == triGroup.a && b == triGroup.b && c == triGroup.c;
  62. }
  63. @Override
  64. public int hashCode() {
  65. return Objects.hash(a, b, c);
  66. }
  67. }

发表评论

表情:
评论列表 (有 0 条评论,118人围观)

还没有评论,来说两句吧...

相关阅读

    相关 总结

    一般地,当我们要去枚举满足条件的区间权值的区间,可以用遍历双指针 l 和 r 的做法去枚举第一个满足条件的区间,然后去维护其他数据,这样的做法就是尺取法,它的复杂度为O(n)

    相关 模板

      题目描述 博览馆正在展出由世上最佳的 M 位画家所画的图画。 wangjy想到博览馆去看这几位大师的作品。 可是,那里的博览馆有一个很奇怪的规定,就是在购买门票

    相关 算法--

    尺取法 尺取法通常是指对数组保存一对下标(起点,终点),然后根据实际情况交替推进两个端点直到得出答案的方法,这种操作很像是尺取虫爬行的方式故得名。 我们先来看看POJ的