NYOJ-12 喷水装置(二)

NYOJ-12 喷水装置(二)

分析:贪心算法
对于输入的每个点,求出能覆盖住矩形的起点和终点,然后按起点排序,如果最小的起点和最大的终点都不能超过矩形的长度范围,则必定无解,取出起始点最靠前的点,然后记录下这个点的终点,遍历这个起点到终点范围内的所有其他的点,并挑选其中终点最靠后的那个点作为下一个终点的位置,并且计数器加一,继续向后遍历,如果有区间接不上,则表明无解,成功遍历到矩形最后,则直接输出计数器的值

代码如下:

import java.util.PriorityQueue;
import java.util.Scanner;

public class Main {

    static class node implements Comparable<node>{
        double l;
        double r;
        public node(double l, double r) {
            this.l=l;
            this.r=r;
        }
        @Override
        public int compareTo(node o) {
            return Double.compare(this.l, o.l);
        }
    }

    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int m, w, h;
        PriorityQueue<node> q;
        int n=sc.nextInt();
        for(int i=0;i<n;++i){
            m=sc.nextInt();
            w=sc.nextInt();
            h=sc.nextInt()/2;
            q=new PriorityQueue<node>();
            int count=0;
            double tail, max;
            for(int j=0;j<m;++j){
                double tempm, tempr;
                tempm=sc.nextInt();
                tempr=sc.nextInt();
                if(tempr>h){
                    tempr=(double) Math.sqrt(tempr*tempr-h*h);
                    q.add(new node(tempm-tempr, tempm+tempr));
                }
            }
            max=tail=0;
            node tempnode=null;
            while(!q.isEmpty()){
                while(!q.isEmpty()&&(tempnode=q.peek()).l<=tail){
                    if(tempnode.r>max)
                        max=tempnode.r;
                    q.poll();
                }
                if(max!=tail){
                    count++;
                    tail=max;
                    if(tail>=w)
                        break;
                }
                else
                    break;
            }
            if(tail<w)
                System.out.println(0);
            else
                System.out.println(count);
        }
        sc.close();
    }
}

下面是一段别人的代码,结构大同小异,运行结果却比我的好得多,
所需时间是我的1/3.6, 内存1/5,并不明白为什么(⊙_⊙)?求指教

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.StringTokenizer;


public class Main {
    static class Node {
        double left;
        double right;

        public Node(double d, double e) {
            this.left = d;
            this.right = e;
        }

    }

    static Comparator<Node> comparator = new Comparator<Node>() {
        public int compare(Node o1, Node o2) {
            return Double.compare(o1.left, o2.left);
        }
    };

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;
        int k = Integer.parseInt(br.readLine());
        while (k-- > 0) {
            st = new StringTokenizer(br.readLine());
            int n = Integer.parseInt(st.nextToken());
            double width = Double.parseDouble(st.nextToken());
            double height = Double.parseDouble(st.nextToken()) / 2;

            PriorityQueue<Node> arr = new PriorityQueue<Node>(n, comparator);
            for (int i = 0; i < n; i++) {
                st = new StringTokenizer(br.readLine());
                double a = Double.parseDouble(st.nextToken());
                double b = Double.parseDouble(st.nextToken());
                if (b > height) {
                    double len = Math.sqrt(b * b - height * height);
                    arr.add(new Node(a - len, a + len));
                }
            }

            double start = 0;
            int count = 0;
            boolean flag = false;
            while (!arr.isEmpty()) {
                double max = Double.MIN_VALUE;
                Node node = null;
                while (!arr.isEmpty() && arr.peek().left <= start) {
                    if (arr.peek().right > max) {
                        max = arr.peek().right;
                        if (node != null)
                            arr.remove(node);
                        node = arr.peek();
                    } else {
                        arr.poll();
                    }
                }
                if (max == Double.MIN_VALUE) {
                    break;
                }
                if (node != null)
                    arr.remove(node);
                if (max > start) {
                    start = max;
                    count++;
                }
                if (start >= width) {
                    flag = true;
                    break;
                }
            }

            System.out.println(flag ? count : 0);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值