洛谷 P1142 轰炸

题面

给出 n (1<=n<=700) 个点,问最多多少个点共线

分析

先把多点共线变成三点共线问题,即取两个定点,判断第三个动点是否与这两个定点共线,动点遍历完所有后,再改变定点。如此能得到一个 O(n3) 的方法(实际上能跑过这个题,因为一方面 C n 2 C_{n}^{2} Cn2 其实近似 n2/2 ,另一方面题的数据量貌似比 700 要小)
如果能解决三点共线问题,就能解决这个多次判定三点共线问题

判断三点共线有较多的做法,比较普遍的有两种:
浮点型:算以一点出发到两点的斜率,判定其是否相等即可,一般要考虑误差,而且可能有斜率不存在情况
向量型:两个向量 ( x 1 , y 1 ) (x_1 , y_1) (x1,y1) ( x 2 , y 2 ) (x_2 , y_2) (x2,y2) 共线当且仅当 x 1 y 2 = x 2 y 1 x_1y_2=x_2y_1 x1y2=x2y1

本题的输入都是整数,所以用向量型更优。

算法也就如下:
1.取定两个点 i , j .
2.从 i 连接另外一个动点 k , 判定 ij 与 ik 是否共线,如果共线则共线点+1
3.回到1步,且改变取定的点

代码

#include "cstdlib"
#include <iostream>
#include<algorithm>
#include<string.h>
#include<string>
using namespace std;
int x[705], y[705];
int main()
{
	ios::sync_with_stdio(false);
	int n;
	cin >> n;
	for (register int i = 0; i < n; i++)cin >> x[i] >> y[i];
	int ans = 0;//保存两个定点下的共线点最大值
	int temp = 0;//保存当前两个定点下的共线点有多少个
	int v1x, v1y;//vector1:x,y,用定点构造
	for (register int i = 0; i < n; i++)
	{
		for (register int j = i+1; j < n; j++)//(i,j)是取的定点,有C(2,n)种取法
		{
			temp = 0;
			v1x = x[i] - x[j];
			v1y = y[i] - y[j];
			for (int k = 0; k < n; k++)//k是第三个动点,ik和ij两条直线共线则temp++;
			{
				if (v1x * (y[i] - y[k]) == v1y * (x[i] - x[k]))temp++;
			}
			ans = max(temp, ans);
		}
	}
	cout << ans;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值