51nod 1451:合法三角形 枚举斜率

来源:互联网 发布:cvr100身份证阅读软件 编辑:程序博客网 时间:2024/06/05 04:32

1451 合法三角形
题目来源: CodeForces
基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题
 收藏
 关注

有n个不同的点,问有多少组三元组能构成面积非0的三角形。

Input
单组测试数据。第一行一个整数n (1 ≤ n ≤ 2000),表示点的数目。接下来n行,每行包含两个整数 xi, yi ( -100 ≤ xi, yi ≤ 100),表示第i个点的坐标。输入保证点是两两不同的。
Output
输出合法的三角形数目。
Input示例
40 01 12 02 2
Output示例
3

完全是水过的,感觉斜率在精度上还可以再卡我几次。。。

一开始按照x点坐标来暴力,T掉了,想也是,一个6层循环。。。

然后考虑枚举斜率,判重。但因为斜率是double型,搞了一个map<double,int>,结果精度上还是不行。

把斜率扩大很多很多倍,开了一个很大很大的数组,一开始memset又把我给T了,最后记录了一下数值,终于算是水过了。

A了之后看了别的人的做法,用double数组记录,排一下序,再去扫一遍判重是一个更好的做法。

代码:

#pragma warning(disable:4996)  #include <iostream>  #include <algorithm>  #include <cmath>  #include <vector>  #include <string>  #include <cstring>#include <map>using namespace std;typedef long long ll;ll n;ll x[2005], y[2005];ll appear[8000005];int vis[8000005];void input(){int i;scanf("%lld", &n);for (i = 1; i <= n; i++)scanf("%lld%lld", &x[i], &y[i]);}void solve(){int i, j, k, h;ll repeat = 0;for (i = 1; i <= n; i++){k = 0;for (j = i + 1; j <= n; j++){double xx = x[j] - x[i];double yy = y[j] - y[i];double res;if (xx == 0){res = 8000004;}else{res = yy / xx * 20000 + 4000000;}int r = res;repeat += appear[r];if (appear[r] == 0){vis[k] = r;k++;}appear[r]++;}for (h = 0; h < k; h++){appear[vis[h]] = 0;}}printf("%lld\n", n*(n - 1)*(n - 2) / 6 - repeat);}int main(){//freopen("i.txt", "r", stdin);//freopen("o.txt", "w", stdout);input();solve();return 0;}

重新写了一下上面那个思路的,这个比之前的靠谱多了,相对来说时间会长一些。

代码:

#pragma warning(disable:4996)  #include <iostream>  #include <algorithm>  #include <cmath>  #include <vector>  #include <string>  #include <cstring>#include <map>using namespace std;typedef long long ll;#define eps 1e-6ll n;ll x[2005], y[2005];double xy[4000005];void input(){int i;scanf("%lld", &n);for (i = 1; i <= n; i++)scanf("%lld%lld", &x[i], &y[i]);}void solve(){ll i, j, k, h;ll repeat = 0;for (i = 1; i <= n; i++){k = 0;for (j = i + 1; j <= n; j++){double xx = x[j] - x[i];double yy = y[j] - y[i];double res;if (xx == 0){res = 4000002;}else{res = yy / xx + 2000000;}xy[k++] = res;}sort(xy, xy + k);j = 0;for (h = 1; h < k; h++){if (abs(xy[h] - xy[j]) > eps){repeat += (h - j)*(h - j - 1) / 2;j = h;}}repeat += (h - j)*(h - j - 1) / 2;}printf("%lld\n", n*(n - 1)*(n - 2) / 6 - repeat);}int main(){//freopen("i.txt", "r", stdin);//freopen("o.txt", "w", stdout);input();solve();return 0;}



0 0
原创粉丝点击