解题报告 轰炸德累斯顿

 

1.        题目

轰炸德累斯顿(Bomb.pas/c/cpp

题目描述

1944年,随着诺曼底登陆的成功,同盟国的军队登上了欧洲西海岸,开辟了第二战场,胜利之日不远了。

为了彻底打击德国的军工制造,你与美国空军一起执行轰炸德国工业重镇——德累斯顿的计划。正当你驾驶“空中堡垒”轰炸机准备投弹时,德军防空火炮击中了你的飞机,现在飞机已经无法转向了,只能沿直线飞行。

地面上的德军目标处在同一平面内,用二维坐标描述。现在你想一次轰炸最多的目标,请完成任务。

输入数据

    输入数据由n对整数组成(1<n<700),每对整数表示一个点的坐标。没有一个点会出现两次。

输出数据

    一个整数,表示能轰炸到的最多的目标数。

样例输入

1 1

2 2

3 3

9 10

10 11

样例输出

3

2.        题目实质

找出一条直线,使其经过给定的点的数量最多。

3.        算法

简单枚举。

首先,储存坐标时开两个坐标系,一个存横坐标,一个存纵坐标,不要开二维数组。

然后枚举一个点(分别枚举),并且枚举他与其他的点所组成的直线的斜率,,跑一遍快排,然后找出斜率相同的最多的点,统计。最后找出枚举的最大值。

4.        注意事项

不要用二维数组存。

判断斜率时如果用除,要判断 0 ,如果用乘,要小心它会乘出来一个特别大的数。

理解题意时要理解对,这个飞机不是从原点出发,而是从给定的飞机中的任意一个出发。

5.        时空复杂度

O(n*(n+n)*logn)

6.        程序代码

Leve  Pascal

var

 n,i,j,ans,now,k:longint;

 x,y:array[1..700] of longint;

procedure qs(r,l:longint);

 var

  i,j,xx,yy,temp:longint;

 begin

  i:=r; j:=l;

  xx:=x[(i+j)>>1];

  yy:=y[(i+j)>>1];

  repeat

   while (x[i]<xx) or ((x[i]=xx) and (y[i]<yy)) do inc(i);

   while (x[j]>xx) or ((x[j]=xx) and (y[j]>yy)) do dec(j);

    if i<=j then

        begin

         temp:=x[i]; x[i]:=x[j]; x[j]:=temp;

         temp:=y[i];y[i]:=y[j]; y[j]:=temp;

         inc(i);

         dec(j);

        end;

   until i>j;

  if i<l then qs(i,l);

  if j>r then qs(r,j);

 end;

begin

 assign(input,'bomb.in');

 assign(output,'bomb.out');

 reset(input);

 rewrite(output);

 n:=0;

 while not eof do

  begin

   inc(n);

   readln(x[n],y[n]);

  end;

  qs(1,n);

 for i:=1 to n do

  for j:=i+1 to n do

   begin

    now:=2;

       for k:=j+1 to n do

         if (y[j]-y[i])*(x[k]-x[i])=(x[j]-x[i])*(y[k]-y[i]) then

          inc(now);

       if now>ans then ans:=now;

    end;

 writeln(ans);

 close(input);

 close(output);

end.

 

 

 

 

 

posted @ 2011-08-06 14:39  木小漾  阅读(221)  评论(0编辑  收藏  举报