思路分析
根据激光点的位置,就可以确定对其他有老鼠点(x, y)的激光发射(并且贯穿平面上的一整条直线)
- 最开始的暴力解法,是想去遍历整个二维平面,计算某一个点和激光点连成的直线上所有有老鼠的点都会被消灭
- 但是,遍历整个二维数组复杂度太高,x和y都是 1 0 4 10^4 104级别的,遍历就是 1 0 8 10^8 108 次
- 此外,某一条直线会出现经过的点不是整数点,那么该如何处理又是一个棘手的问题
- 原问题的巧妙转化:
- 根据题意,其实可以发现一个性质(激光发射一次就是一条直线,那么次数就是所有老鼠的点一共能够画出多少条直线的问题)
- 再进一步转化,就说看一共能画出多少条不同斜率的直线(因为激光点是固定的,所以不同的直线,斜率一定不同)
实现
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef pair<int, int> PII;
const int N = 1010;
double cnt[N]; // cnt中存放的是斜率,是double类型的
int n, x0, y0, ans;
// 原问题转化为,只需要知道一共有多少条斜率即可
bool find_k(double k)
{
for(int i = 0; i < ans; i++){
if(cnt[i] == k) return true;
}
return false;
}
int main()
{
cin >> n >> x0 >> y0;
for(int i = 1; i <= n; i++){
int x, y;
cin >> x >> y;
double k;
if(x == x0) k = 2e4; // 斜率为无穷
else k = 1.0 * (y - y0) / (x - x0);
// 如果没有该斜率记录,则添加
if(!find_k(k)) cnt[ans++] = k;
}
cout << ans << endl;
return 0;
}