LQ0081 直线GCD+数学

Posted 海岛Blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LQ0081 直线GCD+数学相关的知识,希望对你有一定的参考价值。

题目来源:蓝桥杯2021初赛 C++ A组B题

题目描述
在平面直角坐标系中,两点可以确定一条直线。
如果有多点在一条直线上,那么这些点中任意两点确定的直线是同一条。
给定平面上2 × 3 个整点(x, y)|0 ≤ x < 2, 0 ≤ y < 3, x ∈ Z, y ∈ Z,
即横坐标是0 到1 (包含0 和1) 之间的整数、纵坐标是0 到2 (包含0 和2) 之间的整数的点。
这些点一共确定了11 条不同的直线。
给定平面上20 × 21 个整点(x, y)|0 ≤ x < 20, 0 ≤ y < 21, x ∈ Z, y ∈ Z,
即横坐标是0 到19 (包含0 和19) 之间的整数、纵坐标是0 到20 (包含0 和20) 之间的整数的点。
请问这些点一共确定了多少条不同的直线。

问题分析
2点<x1,y1>和<x2,y2>的直线方程是(y1-y2) * x +(x2-x1) * y +( x1 * y2 - x2 * y1)=0。
可以令a=y1-y2,b=x2-x1,c=x1 * y2 - x2 * y1,那么方程kax+kby+kc=0与方程ax+by+c=0为同一直线。

AC的C++语言程序如下:

/* LQ0081 直线 */

#include <iostream>
#include <algorithm>
#include <set>

using namespace std;

const int N = 20, M = 21;
struct Point 
    int x, y;
 p[N * M];

typedef pair<pair<int, int>, int> Line;

int main()

    int cnt = 0;
    for (int i = 0; i < N; i++)
        for (int j = 0; j < M; j++)
            p[cnt].x = i, p[cnt++].y = j;

    set<Line> s;
    for (int i = 0; i < cnt; i++)
        for (int j = i + 1; j < cnt; j++) 
            int a = p[i].y - p[j].y;
            int b = p[j].x - p[i].x;
            int c = p[i].x * p[j].y - p[j].x * p[i].y;
            int gcd = __gcd(__gcd(a, b), c);
            s.insert(a / gcd, b / gcd, c / gcd);
        

    cout << s.size() << endl;

    return 0;

以上是关于LQ0081 直线GCD+数学的主要内容,如果未能解决你的问题,请参考以下文章

三维坐标点到直线的距离公式是啥?

LQ0130 螺旋折线数学规律

3D数学基础:图形与游戏开发 第二章 笛卡尔坐标系统

LQ0004 等差数列GCD

LQ0004 等差数列GCD

Codeforces1548 D1. Gregor and the Odd Cows (Easy)(皮克公式+gcd+数学推导)