喷水装置(二)
时间限制:3000 ms | 内存限制:65535 KB
难度:4
描述
有一块草坪,横向长w,纵向长为h,在它的橫向中心线上不同位置处装有n(n<=10000)个点状的喷水装置,每个喷水装置i喷水的效果是让以它为中心半径为Ri的圆都被润湿。请在给出的喷水装置中选择尽量少的喷水装置,把整个草坪全部润湿。
输入
第一行输入一个正整数N表示共有n次测试数据。
每一组测试数据的第一行有三个整数n,w,h,n表示共有n个喷水装置,w表示草坪的横向长度,h表示草坪的纵向长度。
随后的n行,都有两个整数xi和ri,xi表示第i个喷水装置的的横坐标(最左边为0),ri表示该喷水装置能覆盖的圆的半径。
输出
每组测试数据输出一个正整数,表示共需要多少个喷水装置,每个输出单独占一行。
如果不存在一种能够把整个草坪湿润的方案,请输出0。
样例输入
2
2 8 6
1 1
4 5
2 10 6
4 5
6 5
样例输出
1
2
//这道题我从暑假想到现在,哈哈,还好没放弃
package man;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
class Former implements Comparable<Former>{//原的类
private int radius; //原的排序是根据半径大小来排序
private int x;
public Former(int radius, int x) {
this.radius = radius;
this.x = x;
}
public int getRadius() {
return radius;
}
public void setRadius(int radius) {
this.radius = radius;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
@Override
public int compareTo(Former o) {
// TODO Auto-generated method stub
if(this.getRadius()>o.getRadius())
return -1;
else if(this.getRadius()<o.getRadius())
return 1;
return 0;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return this.getRadius()+" "+this.getX();
}
}
class Flow{
private int w;
private int h;
private int i[]; //用来快速反应 相当于一条线,半径有多长,线就有多长,如果中间有空隙,直接退出,如果有原能够全部包含全部元素,跳出,返回1 0 / 1 元
private List<Former> list=new ArrayList<Former>(); //将数组加入list 中,但是每一个加入前,都需要验证是否被大元包含
public Flow(int w, int h,Former f[]) {
this.w = w;
this.h = h;
for(Former o:f){
if(iscontains(o))
list.add(o);
}
}
public boolean iscontains(Former f){
if(f.getRadius()<this.h/2){
System.out.println(1);
return false;//如果数据还没有半长 舍去
}
if(list==null){
System.out.println(2);
return true;
}else{
for(Former o:list){
//System.out.println(o.getX());
int var=o.getX()-o.getRadius();
// System.out.println(var+";;");
// System.out.println();
if((f.getX()-var)<f.getRadius()) //如果一个元在拧一个原里
{ //System.out.println(3);
return false;
}
}
}
return true;
}
public int ToIntValue(){
int len=list.size();
i=new int [len];
for(Former f:this.list)
{
if(isready(f))
return 1; //如果一个元已经包
int strat=f.getX()-f.getRadius();
if(strat<=0)
strat=0;
int end=f.getX()+f.getRadius();
if(end>=w)
end=w;
for(;strat<end;strat++) //可能数据越界
i[strat]=1;
}
for(int n:this.i)
if(n!=1)
return 0;
return list.size();
}
public boolean isready(Former f){
if((Math.sqrt(Math.pow(f.getX(), 2)+Math.pow(h/2, 2))<f.getRadius())||(Math.sqrt(Math.pow(w-f.getX(), 2)+Math.pow(h/2, 2))<f.getRadius()))
return false;
else
return true;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return ToIntValue()+"";
}
public int getInfo(){
return this.list.size();
}
}
public class Flow_gate {
public static void main(String[] args) {
Former f[]=new Former[]{
new Former(1,1), //注意这里有点不同
new Former(5,4)
};
Arrays.sort(f);
Flow l=new Flow(8,6, f);
// System.out.println(l);
//System.out.println(l.getInfo());
}
}
//可能有错,写出来大家参考参考