jzoj. 3838. 【NOIP2014模拟9.14】Super Big Stupid Cross

来源:互联网 发布:apache教程 编辑:程序博客网 时间:2024/05/29 12:31

Description

“我是超级大沙茶”——Mato_No1
为了证明自己是一个超级大沙茶,Mato 神犇决定展示自己对叉(十字型)有多么的了解。
Mato 神犇有一个平面直角坐标系,上面有一些线段,保证这些线段至少与一条坐标轴平行。Mato 神犇需要指出,这些线段构成的最大的十字型有多大。
称一个图形为大小为R(R 为正整数)的十字型,当且仅当,这个图形具有一个中心点,它存在于某一条线段上,并且由该点向上下左右延伸出的长度为R 的线段都被已有的线段覆盖。
你可以假定:没有两条共线的线段具有公共点,没有重合的线段。

Input

第一行,一个正整数N,代表线段的数目。
以下N 行,每行四个整数x1,y1,x2,y2(x1=x2 或y1=y2),描述了一条线段。

Output

当不存在十字型时:输出一行“Human intelligence is really terrible”(不包括引号)。
否则:输出一行,一个整数,为最大的R。

Sample Input

输入1:
1
0 0 0 1
输入2:
3
-1 0 5 0
0 -1 0 1
2 -2 2 2

Sample Output

输出1:
Human intelligence is really terrible
输出2:
2

Data Constraint

对于50%的数据:N≤1000。
对于100%的数据:1≤N≤100000,所有坐标的范围在-10^9~10^9 中。
后50%内,所有数据均为随机生成。

背景:这题原题好像叫超流超导对撞机,好奇怪的名字。

分析:一开始我是暴力的,50分。然后我发现一个很惊讶的事实。先把长度大到小排序,如果当前长度的一半小于我们已经计算出最大的ans,就可以break掉。正解好像是用二分答案+set维护。

代码:

const maxn=100001;type node=record  x,y,u,v,l:longint; end;arr=array [1..maxn] of node;var a,b:arr; numa,numb,n,i,j,ans,x0,y0,x1,y1,p,l,r,d:longint; flag:boolean;procedure qsort(l,r:longint;var b:arr);  var    i,j,key:longint;    temp:node;  begin    if l>=r then exit;    i:=l;j:=r;    key:=b[l+random(r-l+1)].l;    repeat      while  (b[i].l>key) do inc(i);      while  (b[j].l<key) do dec(j);      if i<=j then      begin        temp:=b[i];b[i]:=b[j];b[j]:=temp;        inc(i);dec(j);      end;    until i>j;    qsort(l,j,b);    qsort(i,r,b);  end;function min(x,y:longint):longint; begin  if x<y then exit(x)         else exit(y); end;procedure swep(var x,y:longint); begin  x:=x xor y;  y:=x xor y;  x:=x xor y; end;begin readln(n); flag:=true; for i:=1 to n do  begin   readln(x0,y0,x1,y1);   if x0=x1 then    begin     if y0>y1 then swep(y0,y1);     inc(numb);     b[numb].x:=x0;     b[numb].y:=y0;     b[numb].u:=x1;     b[numb].v:=y1;     b[numb].l:=y1-y0;    end   else    begin     if x0>x1 then swep(x0,x1);     inc(numa);     a[numa].x:=x0;     a[numa].y:=y0;     a[numa].u:=x1;     a[numa].v:=y1;     a[numa].l:=x1-x0;    end;  end; qsort(1,numb,b); qsort(1,numa,a); for i:=1 to numa do  begin   for j:=1 to numb do    begin     if (b[j].l+1) div 2<=ans then break;     x0:=b[j].x;     y0:=a[i].y;     d:=min(min(x0-a[i].x,a[i].u-x0),min(y0-b[j].y,b[j].v-y0));     if d>ans then ans:=d;    end;   if (a[i].l+1) div 2<=ans then break;  end; if ans=0 then writeln('Human intelligence is really terrible')          else writeln(ans);end.
原创粉丝点击