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);
}
}
}