uva12715 神奇的二分

n条线段m个点,对于每个点,求出控制他的所有线段中控制范围最大的长度:每条范围内线段控制范围=min(x-a[i].l,a[i].r-x)

这个二分好难想到TUT

按左端点从小到大,右端点从大到小排序,要知道在处理之后最大范围肯定出现在相邻两个区间内==thinking

然后二分。。。。。

二分后的两个区间再比较一下。。。。。。

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 using namespace std;
 5 struct dian{
 6   int l,r;
 7 }a[100005];
 8 int x,num;
 9 int cmp(dian n1,dian n2)
10 {
11   if (n1.l==n2.l) return n1.r>n2.r;
12   return n1.l<n2.l;
13 }
14 int judge(int p)
15 {
16   if (p<=0||p>num||x<a[p].l||x>a[p].r) return 0;
17   return min(x-a[p].l,a[p].r-x);
18 }
19 int main()
20 {
21   int T,t,n,m,i,l,r,mid;
22   scanf("%d",&T);
23   for (t=1;t<=T;t++)
24   {
25     scanf("%d%d",&n,&m);
26     for (i=1;i<=n;i++)
27       scanf("%d%d",&a[i].l,&a[i].r);
28     sort(a+1,a+n+1,cmp);
29     num=1;
30     for (i=2;i<=n;i++)
31       if (a[i].r>a[num].r)
32         a[++num]=a[i];//good
33     printf("Case %d:\n",t);
34     while (m--)
35     {
36       scanf("%d",&x);
37       l=1; r=num;
38       while (l<=r)
39       {
40         mid=l+(r-l)/2;
41         if (a[mid].r<x||a[mid].r-x<=x-a[mid].l) l=mid+1;//think=
42         else r=mid-1;
43       }
44     printf("%d\n",max(judge(l),judge(r)));
45     }
46   }
47   return 0;
48 }
View Code

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=49110

posted on 2015-02-09 03:06  xiao_xin  阅读(115)  评论(0编辑  收藏  举报

导航