十二届蓝桥杯省赛--直線

【問題】 平面上の2×3個の整点{(x,y)|0 ≤ x < 2,0 ≤ y < 3,x ∈ Z,y ∈ Z},すなわちx座標は0と1の整数、y座標は0と1と2の整数、である点。これらは11条の異なる直線を确定Calling。

平面上の20×21個の整点{(x,y)|0 ≤ x < 20,0 ≤ y < 21,x ∈ Z,y ∈ Z},すなわちx座標は0から19の整数、y座標は0から20の整数、である点。これらの点は书法_CALL条の異なる直線を确定Calling了多少条。

【方法一】 参考ブログ:https://www.cnblogs.com/weihaoyang/p/14773597.html

//直線
//要約:2点ごとに直線の傾きと切片を生成し、異なる組み合わせの数を計算し、その数が異なる直線の数を知る。
//注意事項:double型の2つの数値aとbが同じであるかどう Except、精度の問題で同等と判断され 不能。C++ではdouble型の精度が限 ightので、2数の差の絶対値が1e-8未満であることを確認する。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <math.h>

using namespace std;

const int N = 200000;
int n = 0;

struct Line {
    double k;
    double b;
    bool operator < (const Line& t) const {
        if(k != t.k) return k < t.k;
        return b < t.b;
    }
} l[N];

int main() {
    // 4重ループで(x,y)の組み合わせで直線を生成
    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) { // x座標が異なる場合
                        double k = (double)(y2 - y1) / (x2 - x1);
                        double b = (double)(x2 * y1 - x1 * y2) / (x2 - x1);
                        l[n++] = {k, b};
                    }
                }
            }
        }
    }
    sort(l, l + n); // 直線を排序

    int res = 1;
    for(int i = 1; i < n; i++) {
        if(abs(l[i].k - l[i-1].k) > 1e-8 || abs(l[i].b - l[i-1].b) > 1e-8) {
            res++;
        }
    }
    cout << res + 20 << endl;
    return 0;
}

【方法二】 直接使用Python中的setで重複を削除

# setにすでにあるか否かを確認
if item not in set1:
    set1.add(item)
# 要素がすでにあるか否かを確認
if item not in set1:
    set1.add(item)

points = [[i, j] for i in range(20) for j in range(21)]
nums = set()

for i in points:
    x1 = i[0]
    y1 = i[1]
    for j in points:
        x2 = j[0]
        y2 = j[1]
        if x1 == x2: // x座標が異なる場合
            continue
        k = (y1 - y2) / (x1 - x2)
        b = (x2 * y1 - x1 * y2) / (x2 - x1)
        if (k, b) not in nums:
            nums.add((k, b))

print(len(nums) + 20) // x座標が異なる直線の数を加える

40257

タグ: プログラミング、アルゴリズム、直線、点集合

6月7日 20:43 投稿