试题 C :直线
一、题目描述
二、算法简析
设两点 \(P_1(x_1, y_1)\) 和 \(P_2(x_2, y_2)\)。
- 斜率为:
\[k = \frac{y_2 - y_1}{x_2 - x_1}
\]
- 斜截式为:
\[\begin{split}
y - y_1 &= k(x - x_1) \\
y - y_1 &= \frac{y_2 - y_1}{x_2 - x_1}(x - x_1)
\end{split}
\]
- 化解为一般式 \(Ax+By=C\):
\[\begin{split}
y - y_1 &= \frac{y_2 - y_1}{x_2 - x_1}(x - x_1)\\
(y - y_1)(x_2 - x_1)&=(y_2 - y_1)(x - x_1) \\
(x_2 - x_1)y - y_1x_2 + y_1x_1 &= (y_2 - y_1)x - y_2x_1 + y_1x_1 \\
(y_2 - y_1)x - (x_2 - x_1)y &= x_1y_2 - x_2y_1 \\
\end{split}
\]
\[\begin{split}
\therefore A &= (y_2 - y_1) \\
B &= x_1 - x_2 \\
C &= x_1y_2 - x_2y_1 \\
\end{split}
\]
- 将 \(A, B, C\) 分别除以三者的最大公约数,得到最简形式。
三、本题代码
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> P;
typedef pair<P, int> line;
vector<P> d;
set<line> S;
int gcd(int a, int b)
{
if (b == 0)
return a;
return gcd(b, a % b);
}
void init(void)
{
for (int i = 0; i < 20; i++)
for (int j = 0; j < 21; j++)
d.push_back(P(i, j));
}
void solve(void)
{
for (int i = 0; i < d.size(); i++)
{
for (int j = i + 1; j < d.size(); j++)
{
int x1 = d[i].first, x2 = d[j].first;
int y1 = d[i].second, y2 = d[j].second;
int A, B, C;
A = y2 - y1;
B = x1 - x2;
C = x1 * y2 - x2 * y1;
int tmp = gcd(gcd(A, B), C);
S.insert(line(P(A / tmp, B / tmp), C / tmp));
}
}
}
int main()
{
init();
solve();
cout << S.size() << endl;
return 0;
}
完
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)