[Kubic] Lines
题目背景
建议先看 C 题题目背景。
题目描述
平面直角坐标系中有 n n n 条直线,任意三条直线不交于一点且没有两条直线重合。显然这些直线形成了不超过 n ( n − 1 ) 2 \dfrac{n(n-1)}{2} 2n(n−1) 个交点。你可以从这些直线中选出一部分,一个点被覆盖当且仅当有至少一条被选中的直线经过了它。求最少选出多少条直线才能覆盖所有交点。
输入格式
第一行,一个整数 n n n。
接下来 n n n 行,每行有三个整数 a , b , c a,b,c a,b,c,表示一条解析式为 a x + b y + c = 0 ax+by+c=0 ax+by+c=0 的直线。
注意:输入数据不保证 gcd ( a , b ) = 1 \gcd(a,b)=1 gcd(a,b)=1。
输出格式
共一行,一个整数,表示答案。
样例 #1
样例输入 #1
3
1 2 3
4 5 6
7 8 10
样例输出 #1
2
提示
对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 1 0 5 , ∣ a ∣ , ∣ b ∣ , ∣ c ∣ ≤ 1 0 9 , a , b 1\le n\le 10^5,|a|,|b|,|c|\le 10^9,a,b 1≤n≤105,∣a∣,∣b∣,∣c∣≤109,a,b 不全为 0 0 0。
分值 | n n n | 特殊性质 | |
---|---|---|---|
Subtask 1 \operatorname{Subtask}1 Subtask1 | 10 10 10 | ≤ 20 \le 20 ≤20 | 无 |
Subtask 2 \operatorname{Subtask}2 Subtask2 | 30 30 30 | ≤ 100 \le 100 ≤100 | 无 |
Subtask 3 \operatorname{Subtask}3 Subtask3 | 10 10 10 | 无特殊限制 | a b = 0 ab=0 ab=0 |
Subtask 4 \operatorname{Subtask}4 Subtask4 | 50 50 50 | 无特殊限制 | 无 |
样例解释
一种方法是选出 x + 2 y + 3 = 0 x+2y+3=0 x+2y+3=0 和 4 x + 5 y + 6 = 0 4x+5y+6=0 4x+5y+6=0 两条线。
可以证明没有更优的方案。
思路
此时我们肯定选的是 7 x + 8 y + 10 = 0 7x+8y+10=0 7x+8y+10=0 和 4 x + 5 y + 6 = 0 4x+5y+6=0 4x+5y+6=0 两条线。
- 我们可以画几张图发现: n n n 条直线两两相交时,需要 n − 1 n-1 n−1 条直线去覆盖。
- 有一个平行线就要去掉一个。
代码
//斜率
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
map<double,int>s;
int n,x;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
double a,b,c;
cin>>a>>b>>c;
s[b/a]++;//斜率相同肯定交点不会被覆盖
x=max(x,s[b/a]);
}
cout<<n-x<<endl;
return 0;
}
//草