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 }
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=49110