高中数学
前面那一道数据小,可以暴力枚举每条直线是否相交。。这个显然不行。
两条直线平行,那么对应的直线方程 ax - by = c 的a和b一定比例是相同的,而且这个题只有整数坐标,所以最后只要是互相平行的直线,a和b一定可以化简成一样的。
所以我们把两点的直线用斜截式化简,可以求出a,b,c,然后除以gcd(a,b),就能把方程化成最简形式了。
最后拿当前的直线数-平行的直线数,就是与我们枚举到这条直线相交的直线数
#include <bits/stdc++.h> #define INF 0x3f3f3f3f #define full(a,b) memset(a,sizeof a) using namespace std; typedef long long ll; inline int lowbit(int x){ return x & (-x); } inline int read(){ int X = 0,w = 0; char ch = 0; while(!isdigit(ch)) { w |= ch == '-'; ch = getchar(); } while(isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48),ch = getchar(); return w ? -X : X; } inline int gcd(int a,int b){ return b ? gcd(b,a % b) : a; } inline int lcm(int a,int b){ return a / gcd(a,b) * b; } template<typename T> inline T max(T x,T y,T z){ return max(max(x,y),z); } template<typename T> inline T min(T x,T z){ return min(min(x,z); } template<typename A,typename B,typename C> inline A fpow(A x,B p,C lyd){ A ans = 1; for(; p; p >>= 1,x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd; return ans; } const int N = 1005; int x[N],y[N],n; map<pair<int,int>,set<int>> m; int main(){ n = read(); for(int i = 1; i <= n; i ++){ x[i] = read(),y[i] = read(); } ll cnt = 0,res = 0; for(int i = 1; i < n; i ++){ for(int j = i + 1; j <= n; j ++){ int x1 = x[i],y1 = y[i],x2 = x[j],y2 = y[j]; int a = y1 - y2,b = x1 - x2,c = y1 * x2 - y2 * x1,f = gcd(a,b); a /= f,b /= f,c /= f; if(a < 0 || (a == 0 && b < 0)) a = -a,b = -b; pair<int,int> g = make_pair(a,b); //int c = a * x1 - b * y1; if(m[g].find(c) == m[g].end()){ cnt ++; m[g].insert(c); res += cnt - m[g].size(); } } } cout << res << endl; return 0; }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。