今日「每日一题」来啦!题目:直线。还没有加入专属刷题群的小伙伴,记得扫码哟~(每天会在群里发蓝桥杯历年真题)
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
在平面直角坐标系中,两点可以确定一条直线。如果有多点在一条直线上, 那么这些点中任意两点确定的直线是同一条。
本题涉及知识点为 枚举&直线方程,并出现在第 12 届蓝桥杯软件类 C/C++ A/B 组、Java A/B 组、Python 组。
在平面直角坐标系中,俩点可以确定一条直线,但俩点有四个坐标值,我们不太好维护四个坐标值是否重复。
我们知道直线的表示方式中,除了俩点式,还有点斜式。点斜式的话, 一个点俩个坐标值和一个斜率值,三个值来确定唯一性,虽然不太好写但是还是勉强能跑出来。
更进一步,如果那个点是在 x 轴或者 y 轴上,那么一个坐标就恒定为 0。只要维护另一个坐标值(其实就是截距)和斜率就好了,简单 map 维护一下,要注意考虑枚举的斜率不存在的情况。
1.Java
import java.util.*;
public class Main {
static int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
public static void main(String[] args) {
Set<Integer> set = new HashSet<>();
Set<String> ans = new HashSet<>();
int x = 19, y = 20;
for (int i = 0; i <= x; i++) {
for (int j = 0; j <= y; j++) {
set.add(i * 100 + j);
}
}
List<Integer> arr = new ArrayList<>(set);
int len = arr.size();
for (int i = 0; i < len; i++) {
int a = arr.get(i);
for (int j = i + 1; j < len; j++) {
int b = arr.get(j);
int x1 = a / 100, x2 = b / 100, y1 = a % 100, y2 = b % 100;
int up = y1 - y2, down = x1 - x2;
int c1 = gcd(up, down);
String K = (up / c1) + " " + (down / c1);
if (down == 0) {
ans.add("x = " + x1);
continue;
}
int kx = up * x1, Y = y1 * down;
int kb = Y - kx;
int c2 = gcd(kb, down);
String B = (kb / c2) + " " + (down / c2);
ans.add(K + " " + B);
}
}
System.out.println(ans.size());
}
}
2.Python
import os
import sys
class Line(object):
def __init__(self):
self.k = 0
self.b = 0
def __lt__(self, t):
if self.k != t.k:
return self.k < t.k
return self.b < t.b
N = 200000
n = 0
l = [Line() for _ in range(N)]
for x1 in range(0, 20):
for y1 in range(0, 21):
for x2 in range(0, 20):
for y2 in range(0, 21):
if x1 != x2:
k = float((y2 - y1)) / (x2 - x1)
b = float(y2 - k * x2)
l[n].k = k
l[n].b = b
n += 1
L = l[0: n]
L.sort()
res = 1
for i in range(1, n):
if abs(L[i].k - L[i - 1].k) > 1e-8 or abs(L[i].b - L[i - 1].b) > 1e-8:
res += 1
print(res + 20)
3.C/C++
typedef long long ll;
using namespace std;
struct Point{
double x, y;
}p[25*25];//存下每一个点
map<pair<double,double> ,int> mp;//存斜率k和截距b
int main(){
int cnt = 0;
for(int i = 0;i < 20;i++){
for(int j = 0;j < 21;j++){
p[cnt].x = i;
p[cnt++].y = j;
}
}
int ans = 20 + 21;
for(int i = 0;i < cnt;i++){
for(int j = 0;j < cnt;j++){
//两点的直线与坐标轴平行或共点
if(p[i].x == p[j].x || p[i].y == p[j].y) continue;
//斜率和截距
double k = (p[j].y - p[i].y) / (p[j].x - p[i].x);
double b = (p[j].x * p[i].y - p[j].y * p[i].x) / (p[j].x - p[i].x);
if(mp[{k,b}] == 0){
mp[{k,b}] = 1;
ans++;
}
}
}
cout << ans << endl;
return 0;
}
//40257
今天的「每日一题」就结束啦~备战第 14 届蓝桥杯的小伙伴,快来一起刷题吧~
▼加入蓝桥杯备赛刷题▼
推荐站内搜索:最好用的开发软件、免费开源系统、渗透测试工具云盘下载、最新渗透测试资料、最新黑客工具下载……
还没有评论,来说两句吧...