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+数学的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces1548 D1. Gregor and the Odd Cows (Easy)(皮克公式+gcd+数学推导)