您的位置:首页 > 其它

【算法】轰炸(BOMB)解题报告(模拟提高组)

2016-11-07 22:52 127 查看
轰炸(BOMB)

源程序名       bomb  (pas,c,cpp)

可执行文件名   bomb.exe

输入文件名     bomb.in

输出文件名     bomb.out

时限           2s

“我该怎么办?”飞行员klux向你求助。

事实上,klux面对的是一个很简单的问题,但是他实在太菜了。

klux要想轰炸某个区域内的一些地方,它们是位于平面上的一些点,但是(显然地)klux遇到了抵抗,所以klux只能飞一次,而且由于飞机比较破,一点起飞就只能沿直线飞行,无法转弯。现在他想一次轰炸最多的地方。

输入:

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

输出:

一个整数,表示一条直线能覆盖的最多的点数。

样例:

bomb.in

1 1

2 2

3 3

9 10

10 11

bomb.out

3

说明:

本题翻译并改编自uva270,数据及解答由uva提供。

        代码,由于时间紧迫,我写了个时间复杂度是O(N^3)的代码,不过不会超时间,最长的也不过0.8秒,这个代码的基本思想就是先选择两个点,计算出直线方程,然后再看其余点是否符合该直线方程,统计一共有几个点共线。这样一来,找出两个点的复杂度是O(N^2),看其他点是否在直线上的复杂度为O(N) !!

代码如下:

#include
#include
#define x 0
#define y 1
using namespace std ;
int main(){
ifstream fin  ( "bomb.in"  );
ofstream fout ( "bomb.out" );
int n , i , j , k , A , B , C , counter , max(0) ;
fin >> n ;
int p[n + 1][2] ;
for ( i = 1 ; i <= n ; i++ ) fin >> p[i][x] >> p[i][y] ;
for ( i = 1 ; i < n ; i++ )
for ( j = i + 1 ; j <= n ; j++ )
{
A = p[i][y] - p[j][y] ;
B = p[i][x] - p[j][x] ;
C = B * p[i][y] - A * p[i][x] ;
counter = 2 ;
for ( k = 1 ; k <= n ; k++ )
if ( k != i && k != j )
if ( A*p[k][x] - B*p[k][y] + C == 0 ) counter++ ;
if ( max < counter ) max = counter ;
}
fout << max << endl ;
}


几点注释:

直线斜率: k = (y1-y2)/(x1-x2)

斜截式:   y = kx + b

            = ((y1-y2)/(x1-x2)) x + b

          b = y - kx = y1 - ((y1-y2)/(x1-x2))x1

转换:  (x1-x2)y = (y1-y2)x + (x1-x2)b

       (y1-y2)x - (x1-x2)y + (x1-x2)b = 0

直线标准方程:  Ax - By + C = 0

  A = (y1-y2) , B = (x1-x2) , C = (x1-x2)b = y1(x1-x2) - (y1-y2)x1
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: