pku 1727 Advanced Causal Measurements (ACM) 二分+贪心可行性判断

题目说的有点诡异,一开始没想到二分,想直接通过半平面交来解或者是线性规划。。。
描述下题目平面上有一些点(x,t)(题目中描述的是(t,x),然后t是纵坐标,有点不舒服),然后满足t2 >= t1+|x2-x1|的点(t1,x1)称为点(x2,t2)的前导点。现在知道平面点集以及其前导点的个数,问其前导点集中t的最大值。
根据不等式,可以发现每个点的前导点集范围是一个以该点为顶点的三角形区域(根据不等式约束画个图看看就明白了),然后可以通过二分求得t,关于判断当前t的可行性,将每个点表示为合法区间[x2-(t2-t1),x2+t2-t1],然后求这些区间的最小覆盖数(就是求得一些子区间,使得这些子区间包含于原区间)。这个问题可以通过贪心算法,以区间右端点为第一关键字,左端点为第二关键字进行排序,然后每次贪心的选择当前区间的右端点作为子区间,统计要导出全部区间需要子区间的个数num。
代码如下:
 1 import java.io.*;
 2 import java.util.Arrays;
 3 public class Main {
 4 
 5     /**
 6      * @param args
 7      */
 8     static StreamTokenizer in=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
 9     //static StreamTokenizer in=new StreamTokenizer(new BufferedReader(new InputStreamReader(new FileInputStream("input.txt"))));
10     static final int readInt() throws Exception
11     {
12         in.nextToken();
13         return (int)in.nval;
14     }
15     static class node implements Comparable<node>
16     {
17         int t,x,s,e;
18         public int compareTo(node pos)
19         {
20             if(e!=pos.e) return e-pos.e;
21             else return s-pos.s;
22         }
23     }
24     static node data[]=new node[100005];
25     public static void main(String[] args) throws Exception{
26         int n=readInt();
27         for(int i=0;i<100005;i++)
28             data[i]=new node();
29         for(int test=1;test<=n;test++)
30         {
31             int num=readInt(),limit=readInt(),e=4000000,s=-4000000;
32             for(int i=0;i<num;i++)
33             {
34                 data[i].t=readInt();
35                 data[i].x=readInt();
36                 e=Math.min(e, data[i].t);
37             }
38             while(s<=e)
39             {
40                 int mid=(s+e)>>1,count=1;
41                 for(int i=0;i<num;i++)
42                 {
43                     data[i].s=data[i].x-data[i].t+mid;
44                     data[i].e=data[i].x+data[i].t-mid;
45                 }
46                 
47                 Arrays.sort(data,0,num);
48                 int laste=data[0].e;
49                 for(int i=1;i<num;i++)
50                     if(data[i].s<=laste)
51                         continue;
52                     else
53                     {
54                         count++;
55                         laste=data[i].e;
56                     }
57                 if(count<=limit)
58                     s=mid+1;
59                 else
60                     e=mid-1;
61             }
62             System.out.println("Case "+test+""+e);            
63         }
64 
65     }
66 
67 }
68 

posted on 2010-10-20 00:36 yzhw 阅读(329) 评论(0)  编辑 收藏 引用 所属分类: searchnumberic


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2010年10月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

导航

统计

公告

统计系统

留言簿(1)

随笔分类(227)

文章分类(2)

OJ

最新随笔

搜索

积分与排名

最新评论

阅读排行榜