C:直线 蓝桥杯b组

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

【答案】
40257

基本思路:
通过点斜式y=kx+b确定每条直线唯一的k和b。
其中:
k=(y2-y1)/(x2-x1) (这里并没有用double进行存储,将分母分子通分后,再存入string类型,下同)
b=(x1y2-x2y1)/(x1-x2)

代码

import java.util.*;

public class Main {
	
	public static void main(String[] args) {
		Set<String> set=new HashSet<String>();
		//四个for循环为两两确定一个坐标
		for (int x1 = 0; x1 < 20; x1++) {
			for (int y1 = 0; y1 < 21; y1++) {
				for (int x2 = 0; x2 < 20; x2++) {
					for (int y2 = 0; y2 < 21; y2++) {
						//如果两点相同则跳过
						if (x1==x2 && y1==y2) {
							continue;
						}
						int up =x2-x1;
						int down =y2-y1;
						if (x1==x2) {
							set.add("x="+x1);
							continue;
						}
						int tmp=gcd(up,down);
						String k=down/tmp+"/"+up/tmp;
						
						up=x1*y2-x2*y1;
						down=x1-x2;
						tmp=gcd(up,down);
						String b=up/tmp+"/"+down/tmp;
						
						String key=k+" "+b;
						set.add(key);
					}
				}
			}
		}
		System.out.println(set.size());
	}
	
	public static int gcd(int x ,int y) {
		return y==0 ? x : gcd(y,x%y);
	}
	
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值