试题 B: 直线 【第十二届蓝桥杯省赛 C/C++大学 A 组 第一场】
试题 B: 直线
本题总分:5 分
【问题描述】
在平面直角坐标系中,两点可以确定一条直线。如果有多点在一条直线上,那么这些点中任意两点确定的直线是同一条。
给定平面上 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) 之间的整数的点。请问这些点一共确定了多少条不同的直线。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
思路:
直线的一般式:ax+by+c=0 。因为两点能确定一条直线,故利用两层循环,让所有点两两连接构成直线,并在fun函数中判重(一条直线由一般式中的a,b,c三个参数确定,可利用一个三维数组储存这些参数)。
如:bool m[3][4][5]=true,即表示直线3x+4y+5=0已经存在了。
细节问题:
1,数组的下标不能是负数啊,参数如果是负数的话怎么办?
答:根据数据范围,a,b都在-20到20之间,c在-19*20到19*20=380之间,那我们记录的时候只需要给这三个参数都加上一个定值,能让最小的负数也能成正数就行了。
如:bool m[-3+50][4+50][-5+500]=true,即表示直线-3x+4y-5=0已经存在了。
2,怎么化简直线方程?
答:每个参数都除以(a,b,c)三个参数的绝对值 的最大公约数,用__gcd(abs(a),__gcd(abs(b),abs(c))即可
3,比如-2x+y+1=0和2x-y-1=0都是最简直线方程,如何判重?
答:其实很好判重,只是容易漏掉这个细节.......
答案:40257
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef double db; 5 #define rep(i,a,n) for (ll i=a;i<=n;i++) 6 #define per(i,a,n) for (ll i=n;i>=a;i--) 7 #define Y 20 8 #define X 19 9 const int MAXN = 1e5 + 10; 10 const int INF = 0x3f3f3f; 11 12 bool m[100][100][1000]; 13 14 struct node{ 15 int x,y; 16 }p[MAXN]; 17 18 void fun(int x1,int y1,int x2,int y2){ 19 int a=y2-y1; 20 int b=x1-x2; 21 int c=y1*x2-x1*y2; 22 int t=__gcd(abs(a),__gcd(abs(b),abs(c))); 23 //t是这三个参数的最大公约数 24 a=a/t+50; 25 b=b/t+50; 26 c=c/t+500; 27 //设置一个定值,防止数组下标出现负数 28 if (!m[100-a][100-b][1000-c]) 29 //最简方程判重 30 m[a][b][c]=true; 31 } 32 33 int main(){ 34 35 int n=0; 36 rep(i,0,Y){ 37 rep(j,0,X){ 38 ++n; 39 p[n].x=j; 40 p[n].y=i; 41 } 42 }//枚举出所有的点,一共420个点 43 44 rep(i,1,n){ 45 rep(j,1,n){ 46 if(j!=i){ 47 int x1=p[i].x , y1=p[i].y; 48 int x2=p[j].x , y2=p[j].y; 49 fun(x1,y1,x2,y2); 50 //直线判重 51 } 52 } 53 }//让所有点两两连接成直线 54 55 ll sum=0;//记录所有不重复的直线 的数量 56 rep(i,0,99){ 57 rep(j,0,99){ 58 rep(k,0,999){ 59 if (m[i][j][k]) sum++; 60 } 61 } 62 } 63 cout<<sum; 64 return 0; 65 }
后记:
虽然代码不是最简单的,但自认为是最简单朴素的思路,绝对人人都能理解(沾沾自喜)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具