【HDOJ5714】拍照(线性扫描)

题意:小明在旅游的路上看到了一条美丽的河,河上有许多船只,有的船只向左航行,有的船只向右航行。小明希望拍下这一美丽的风景,并且把尽可能多的船只都完整地拍到一张照片中。

小明位于河的边上,并且可以在河边的任意位置进行拍照,照相机的视野恰好为90度角,只能以垂直于河边的方向进行拍照。河上的船只全都可看作是平行于河边的一条线段,跟河边的距离各不相同,有的正在向左移动,有的正在向右移动,但移动速度恰好都是一样的。小明可以等待恰当的时间让尽量多的船只都走进照相机的视野里,你不需要考虑船只之间会互相遮挡视野的情况。

下面T组数据,对于每组数据:
第一行是一个数n(1n104),表示船只的数量。
接下来n行,每行四个整数
x,y,z,d(10^6x<y10^6,1z104),表示船只的左端点位置、右端点位置、距离河边的距离,以及航行的方向。d1表示向左航行,1表示向右航行。

思路:首先画图

发现船[x,y,z]只有在[y-z,x+z]的区域内能看到

然后因为速度一样,则向同一方向的船只的相对位置是一样的,可以把它们看成线段

正着做一次前缀和,反着做一次,求两个前(后)缀和之和的最大值即可

哈希新姿势

 1 var a,b,c,d,f1,f2,g1,g2,h:array[1..30000]of longint;
 2     hash:array[-1500000..1500000]of longint;
 3     cas,v,n,m,i,tmp,ans,s1,s2,n1,up,x1,y1,z1,d1:longint;
 4 
 5 procedure swap(var x,y:longint);
 6 var t:longint;
 7 begin
 8  t:=x; x:=y; y:=t;
 9 end;
10 
11 function max(x,y:longint):longint;
12 begin
13  if x>y then exit(x);
14  exit(y);
15 end;
16 
17 procedure qsort(l,r:longint);
18 var i,j,mid:longint;
19 begin
20  i:=l; j:=r; mid:=h[(l+r)>>1];
21  repeat
22   while mid>h[i] do inc(i);
23   while mid<h[j] do dec(j);
24   if i<=j then
25   begin
26    swap(h[i],h[j]);
27    inc(i); dec(j);
28   end;
29  until i>j;
30  if l<j then qsort(l,j);
31  if i<r then qsort(i,r);
32 end;
33 
34 begin
35  assign(input,'hdoj5714.in'); reset(input);
36  assign(output,'hdoj5714.out'); rewrite(output);
37  readln(cas);
38  for v:=1 to cas do
39  begin
40   readln(n1);
41   up:=0; n:=0; m:=0;
42   for i:=1 to n1 do
43   begin
44    readln(x1,y1,z1,d1);
45    if y1-z1<=x1+z1 then
46    begin
47     inc(n); a[n]:=y1-z1; b[n]:=x1+z1; d[n]:=d1;
48     inc(m); h[m]:=y1-z1;
49     inc(m); h[m]:=x1+z1;
50    end;
51   end;
52   if m>0 then qsort(1,m);
53   for i:=1 to m do
54    if hash[h[i]]=0 then
55    begin
56     inc(up); hash[h[i]]:=up;
57    end;
58   fillchar(f1,sizeof(f1),0);
59   fillchar(f2,sizeof(f2),0);
60   fillchar(g1,sizeof(g1),0);
61   fillchar(g2,sizeof(g2),0);
62   for i:=1 to n do
63    if d[i]=1 then
64    begin
65     inc(f1[hash[a[i]]]);
66     dec(g1[hash[b[i]]]);
67    end
68     else
69     begin
70      inc(f2[hash[a[i]]]);
71      dec(g2[hash[b[i]]]);
72     end;
73   s1:=0; s2:=0; ans:=0; tmp:=0;
74   for i:=1 to up do
75   begin
76    s1:=s1+f1[i];
77    tmp:=max(tmp,s1);
78    s1:=s1+g1[i];
79    s2:=s2+f2[i];
80    ans:=max(ans,tmp+s2);
81    s2:=s2+g2[i];
82   end;
83   writeln('Case #',v,':');
84   writeln(ans);
85   for i:=1 to m do hash[h[i]]:=0;
86  end;
87 
88  close(input);
89  close(output);
90 end.
原文地址:https://www.cnblogs.com/myx12345/p/7383892.html