持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情
虽然是C++组的,但是和Java组的差不了两道题,大家都可以看一看 如有错误,还请佬 评论或私信指出(写的稍些急) 再也不肝博客了 /(ㄒoㄒ)/~~
(由于上传图片有限制,如果描述不清楚点击手写题解) 手写题解字丑,但是小编感觉会比文字看的直观一些(其实是不会用数学公式)
C++B组手写题解(如果访问出错,请刷新访问的页面即可(Nebo的问题))
当前页面的编程题均在C语言网成功运行 C语言网有各届蓝桥杯的题库 第十二届蓝桥杯编程题测试 刷题集
试题 C: 直线
本题总分:10 分
【问题描述】
在平面直角坐标系中,两点可以确定一条直线。如果有多点在一条直线上,
那么这些点中任意两点确定的直线是同一条。
给定平面上 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) 之
间的整数的点。请问这些点一共确定了多少条不同的直线。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一
个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分
package LanqiaobeiExam._12CB;
import java.util.*;
/**
* ClassName: C直线
* Package: LanqiaobeiExam._12CB
*
* @DATE: 2022/3/21 15:29
* Author: asleep
*/
public class C直线 { //40257
public static class Node {
int x, y;
public Node(int x, int y) {
this.x = x;
this.y = y;
}
double x1, y1;
public Node(double x1, double y1) {
this.x1 = x1;
this.y1 = y1;
}
}
public static class Line {
int a, b, c;
public Line(int a, int b, int c) {
this.a = a;
this.b = b;
this.c = c;
}
@Override
public boolean equals(Object o) {
Line line = (Line) o;
return a == line.a && b == line.b && c == line.c;
}
@Override
public int hashCode() {
return Objects.hash(a, b, c);
}
}
public static int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
public static int gcd(int a, int b, int c) {
return gcd(gcd(a, b), gcd(b, c));
}
public static void main(String[] args) {
//方法一 两点式
{
int n = 20, m = 21;
Set<Line> set = new HashSet<>();
Node[] node = new Node[1000];
int index = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
node[index++] = new Node(i, j);
}
}
for (int i = 0; i < index; i++) {
for (int j = i + 1; j < index; j++) {
int a = node[i].y - node[j].y;//系数
int b = node[j].x - node[i].x;
int c = node[i].y * (node[i].x - node[j].x) - node[i].x * (node[i].y - node[j].y);
int g = gcd(Math.abs(a), Math.abs(b), Math.abs(c));
set.add(new Line(a / g, b / g, c / g));
}
}
System.out.println(set.size());
}
//方法二: y = kx+b 确定直线
{
List<Integer> points = new ArrayList<>();
Set<String> ans = new HashSet<>();
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 21; j++) {
points.add(i * 100 + j); //存xy
}
}
int size = points.size();
for (int i = 0; i < size; i++) {
int node1 = points.get(i);
int x1 = node1 / 100, y1 = node1 % 100;
for (int j = i + 1; j < size; j++) {
int node2 = points.get(j);
int x2 = node2 / 100, y2 = node2 % 100;
int up = y1 - y2, down = x1 - x2;
if (down == 0) {
ans.add("x = " + x1);
continue;
}
int c1 = gcd(up, down);
String K = up / c1 + " " + down / c1;
int Up = y1 * down - x1 * up;
int c2 = gcd(Up, down);
String B = Up / c2 + " " + down / c2;
ans.add(K + " " + B);
}
}
System.out.println(ans.size());
}
//方法三:
{
//两点式两个点交换后为一条新的直线,需要除 2
Set<Line> set = new HashSet<>();
int n = 20, m = 21;
for (int x1 = 0; x1 < n; x1++) {
for (int y1 = 0; y1 < m; y1++) {
for (int x2 = 0; x2 < n; x2++) {
for (int y2 = 0; y2 < m; y2++) {
if (x1 == x2 && y1 == y2) { //两个相同的点不能确定直线
continue;
}
int a =y1 - y2, b = x2 - x1;
int c = x1 * (y2 - y1) - y1 * (x2 - x1);
int g = gcd(Math.abs(a), Math.abs(b), Math.abs(c));
set.add(new Line(a / g, b / g, c / g));
}
}
}
}
System.out.println(set.size() / 2);
}
}
}
#include "iostream"
#include "algorithm"
#include "cmath"
using namespace std;
struct Node { //40257
double k, b;
bool operator< (const Node& node) const { //自定义排序方法,先按照k的大小排序,k相等时按照b的大小排序
if (k != node.k) {
return k < node.k;
}
return b < node.b;
}
}nodes[200000];;
int main() {
int index= 0; //遍历两个xy
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) { //斜率是0,一共有二十条,后面直接加
continue;
}
double k = (double)(y2 - y1) / (x2 - x1);
double b = y1 - k * x1;
nodes[index++] = {k, b};
}
}
}
}
sort(nodes, nodes + index);
int res = 1; //默认第一个就存在了
for (int i = 1; i < index; i++) { //小数是有误差的,当误差比10的-8次方小,我们就认为是一条直线
if (fabs(nodes[i].k - nodes[i - 1].k) > 1e-8 || fabs(nodes[i].b - nodes[i - 1].b) > 1e-8) {
res++;
}
}
cout << res + 20;
return 0;
}