题目大意 给N(1<n<=1w)个牛的坐标xi,yi(0<=|xi,yi|<=1w 求其他点到没有牛的点的最短曼哈顿距离和以及这些点有多少个.
我语文不好= - =连接:http://poj.org/problem?id=3270
我果然还是若菜呢。很难过吧,自己还是半吊子水平,这种题目都想不出来!
首先,因为是曼哈顿距离,所以X,Y轴可以分开来算,
然后,这道题稍微算一下就能发现,对于x y轴 从该行/列到其他的点的x距离(或y距离)是一个单谷函数...反正就是类似于二次函数的那种图像啦(>﹏<)
所以很明显 解就在x y的最低处所形成的矩形当中,只要从中剔除出有奶牛的地方就好了~~~
还有!!!有可能会有最后得到的矩形只包含一个点并且那个点有奶牛的情况!这个时候只要判断一下这个点的周围是否是最优解(因为奶牛必定不相临)就行啦~!~
拉拉拉拉拉= - =。。NOIP幸运A+++++考了450= - =。。。。就这样一路RP++++下去吧!@!~!~!
code:
var
xl,yl,xr,yr,n,sum,tmp,min,count,i,j,k:longint;
flag:boolean;
x,y,xx,yy:array[-10001..10001] of longint;
a,b:array[0..10005] of longint;
begin
read(n);
fillchar(x,sizeof(x),0);
fillchar(y,sizeof(y),0);
for i:=1 to n do
begin
read(a[i],b[i]);
x[a[i]]:=x[a[i]]+1;
y[b[i]]:=y[b[i]]+1;
end;
fillchar(xx,sizeof(xx),0);
fillchar(yy,sizeof(yy),0);
sum:=0;tmp:=0;
for i:=-10000 to 10000 do
begin
tmp:=tmp+sum;
xx[i]:=xx[i]+tmp;
sum:=sum+x[i];
end;
sum:=0;tmp:=0;
for i:= 10000 downto -10000 do
begin
tmp:=tmp+sum;
xx[i]:=xx[i]+tmp;
sum:=sum+x[i];
end;
sum:=0;tmp:=0;
for i:=-10000 to 10000 do
begin
tmp:=tmp+sum;
yy[i]:=yy[i]+tmp;
sum:=sum+y[i];
end;
sum:=0;tmp:=0;
for i:= 10000 downto -10000 do
begin
tmp:=tmp+sum;
yy[i]:=yy[i]+tmp;
sum:=sum+y[i];
end;
min:=maxlongint;xr:=10000;yr:=10000;
for i:=-10000 to 10000 do
begin
if xx[i]<min then
begin
xl:=i;
min:=xx[i];
end;
if xx[i]>min then
begin
xr:=i-1;
break;
end;
end;
min:=maxlongint;
for i:=-10000 to 10000 do
begin
if yy[i]<min then
begin
yl:=i;
min:=yy[i];
end;
if yy[i]>min then
begin
yr:=i-1;
break;
end;
end;
count:=0;
for i:=xl to xr do
for j:=yl to yr do
begin
flag:=true;
if (x[i]>0) and (y[j]>0) then
for k:=1 to n do
if (a[k]=i) and (b[k]=j) then
begin
flag:=false;
break;
end;
if flag then count:=count+1;
end;
if count>0 then
begin
writeln(xx[xl]+yy[yl],' ',count);
halt;
end;
min:=maxlongint;
for i:=xl-10 to xr+10 do
for j:=yl-10 to yr+10 do
if (i=xl) and (j=yl) then continue else
begin
flag:=false;
for k:=1 to n do
if (a[k]=i) and (b[k]=j) then
begin
flag:=true;
break;
end;
if flag then continue;
if (xx[i]+yy[j])<min then
begin
min:=xx[i]+yy[j];
count:=0;
end;
if (xx[i]+yy[j])=min then count:=count+1;
end;
writeln(min,' ',count);
end.
代码略长呢!!!