题意:给出n条直线,问交点个数
Example
input
Copy
3 2 0 0 1 1 0 1 1 0 2 0 0 0 1 1 0 1 1 2 0 0 1 1 0 0 1 1
output
Copy
1 0 1
//1:取一对边,将问题化为无向图的模型
//2:用pair和map类型将过程模拟
//数学知识太过于匮乏,代码能力弱,图论数论了解少
//用scanf 不要用cin
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
typedef long long ll;
typedef pair <double, double> pdd;
int t;
ll n;
pdd a[N];
map <double, ll> ma;//一个映射的数据类型
map <pdd, ll> mb;
int main()
{
scanf("%d", &t);
while (t--)
{
ma.clear();
mb.clear();
ll ans;
scanf("%lld", &n);
for (int i = 1; i <= n; i++)//第一步:将所有的斜率和截距放入pair-a[i]中
{
int x1, x2, y1, y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
if (x2 == x1)
{
a[i].first = 2e9 + 1;//斜率
a[i].second = x1;//截距
}
else
{
a[i].first = 1.0 * (y2 - y1) / (x2 - x1);//斜率
a[i].second = y1 - (a[i].first * x1);//截距公式
}
ma[a[i].first]++;//第二步骤:将截距放入ma中,将这个pair放入mb中
mb[a[i]]++;
}
ans = n * (n - 1) / 2;//第三步:求出总数
for (int i = 1; i <= n; i++)//第四步:将斜率相同的东西全部减去
{
if (ma[a[i].first] > 1)
{
ll tmp = ma[a[i].first];
ans -= tmp * (tmp - 1) / 2;
ma[a[i].first] = 0;
}
}
for (int i = 1; i <= n; i++)//第五步:将斜率相同并且截距相同的再加上
{
if (mb[a[i]] > 1)
{
ll tmp = mb[a[i]];
ans += tmp * (tmp - 1) / 2;
mb[a[i]] = 0;
}
}
printf("%lld\n", ans);
}
return 0;
}