【問題】 平面上の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