- 题目链接:https://nanti.jisuanke.com/t/43704
- 题意:给定你一系列点,判断能组成多少个三角形。
- 分析:因为一共也就100个点,所以直接暴力O(n3)即可。
判断三个点是否可以组成三角形:
(1)斜率不存在,即三个点横坐标相等。
(2)斜率存在,如果两两斜率相等,就无法组成三角形。
这里需要注意的是,如果用y1-y2/x1-x2这种方式计算斜率,最后判断两个斜率是否相等,是行不通的。因为考虑到除法结果需要转换到double,就有精度的问题,于是 y1-y2/x1-x2 = y2-y3/x2-x3 等价替换为乘法,即 (y1-y2)(x2-x3) = (y2-y3)(x1-x2)。
- 代码
#include<bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define pb push_back
typedef long long ll;
const int maxn = 1e2 + 5;
int n,t = 1,k;
typedef struct{
double x;
double y;
}Point;
vector<Point> vp;
bool ok(Point p1,Point p2, Point p3){
bool check = true;
double a1,a2;
if (p1.x == p2.x && p2.x == p3.x) {
check = false;
}else{
a1 = (p1.y-p2.y)*(p2.x-p3.x);
a2 = (p2.y-p3.y)*(p1.x-p2.x);
if (a1 == a2) {
check = false;
}
}
return check;
}
int main(){
cin>>n;
for (int kase = 0; kase < n; kase++) {
vp.clear();
cin>>k;
double x,y;
for (int i = 0; i < k; i++) {
cin>>x>>y;
vp.pb((Point){
x,y});
}
int ans = 0;
for (int i = 0; i < k; i++) {
for (int j = i+1; j < k; j++) {
for (int m = j+1; m < k; m++) {
if (ok(vp[i],vp[j],vp[m])) {
ans++;
}
}
}
}
printf("Test case #%d: %d triangle(s) can be formed.\n",t,ans);
cout<<endl;
t++;
}
return 0;
}
- 遇到的问题
问题就是判断斜率相等了。double类型的值相等如果是除法,考虑到精度问题等,基本不可靠。