AcWing——4309.消灭老鼠【灵活巧妙转化原问题】

4309. 消灭老鼠 - AcWing题库

思路分析

根据激光点的位置,就可以确定对其他有老鼠点(x, y)的激光发射(并且贯穿平面上的一整条直线)

  1. 最开始的暴力解法,是想去遍历整个二维平面,计算某一个点和激光点连成的直线上所有有老鼠的点都会被消灭
    1. 但是,遍历整个二维数组复杂度太高,x和y都是 1 0 4 10^4 104级别的,遍历就是 1 0 8 10^8 108
    2. 此外,某一条直线会出现经过的点不是整数点,那么该如何处理又是一个棘手的问题
  2. 原问题的巧妙转化:
    1. 根据题意,其实可以发现一个性质(激光发射一次就是一条直线,那么次数就是所有老鼠的点一共能够画出多少条直线的问题)
    2. 再进一步转化,就说看一共能画出多少条不同斜率的直线(因为激光点是固定的,所以不同的直线,斜率一定不同)
      在这里插入图片描述

实现

#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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值