Topic links: https://codeforces.com/contest/1036/problem/E
Thinking: learned integer points on a line segment equal to the GCD (x1 - x2, y1 - y2) + 1, then go to the whole weight of repeating segments intersecting point.
AC Code:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const double eps = 1e-8; 5 const int maxn = 1e3 +5 ; 6 int sgn(double x) 7 { 8 if(fabs(x) < eps) return 0; 9 else return x < 0 ? -1 : 1; 10 } 11 struct Point{ 12 double x, y; 13 Point(){} 14 Point(double _x, double _y){ 15 x = _x, y = _y; 16 } 17 void input(){ 18 scanf("%lf%lf", &x, &y); 19 } 20 bool operator == (Point b) const{ 21 return sgn(x - b.x) == 0 && sgn(y - b.y) == 0; 22 } 23 bool operator < (Point b)const{ 24 return sgn(x - b.x) == 0 ? sgn(y - b.y < 0) : x < b.x; 25 } 26 Point operator - (const Point &b)const{ 27 return Point(x - b.x, y - b.y); 28 } 29 double operator ^(const Point &b){ 30 return x * b.y - y * b.x; 31 } 32 double operator *(const Point &b){ 33 return x * b.x + y * b.y; 34 } 35 }; 36 struct Line{ 37 Point s, e; 38 Line(){} 39 Line(Point _s, Point _e){s = _s, e = _e;} 40 bool operator == (Line v){ 41 return (s == v.s) && (e == v.e); 42 } 43 void input(){ 44 s.input(); 45 e.input(); 46 } 47 int segcrossing(Line v) 48 { 49 int d1 = sgn((e - s)^(v.s - s)); 50 int d2 = sgn((e - s)^(v.e - s)); 51 int d3 = sgn((v.e - v.s)^(s - v.s)); 52 int d4 = sgn((v.e - v.s)^(e - v.s)); 53 if( (d1^d2) == -2 && (d3^d4) == -2 )return 2; 54 return (d1 == 0 && sgn((v.s - s)*(v.s - e)) <= 0) || 55 (d2 == 0 && sgn((v.e - s)*(v.e - e)) <= 0) || 56 (d3 == 0 && sgn((s - v.s)*(s - v.e))<=0) || 57 (d4 == 0 && sgn((e - v.s)*(e - v.e))<=0); 58 } 59 Point crosspoint(Line v){ 60 double a1 = (v.e - v.s)^(s - v.s); 61 double a2 = (v.e - v.s)^(e - v.s); 62 return Point((s.x*a2 - e.x*a1)/(a2 - a1),(s.y*a2 - e.y*a1)/(a2 - a1)); 63 } 64 }; 65 Line l[maxn]; 66 int main() 67 { 68 std::ios::sync_with_stdio(false); 69 int n; 70 cin >> n; 71 ll ans = 0; 72 int x1, x2, y1, y2; 73 for(int i = 0;i < n;i++){ 74 cin >> x1 >> y1 >> x2 >> y2; 75 l[i] = Line(Point((double)x1, (double)y1), Point((double)x2, (double)y2)); 76 ans += __gcd(abs(x1 - x2), abs(y1 - y2)) + 1; 77 } 78 for(int i = 0;i < n;i++) 79 { 80 set< pair<int, int> >st; 81 for(int j = i + 1;j < n;j++) 82 { 83 if(l[i].segcrossing(l[j])){ 84 Point v = l[i].crosspoint(l[j]); 85 if((int)v.x == v.x && (int)v.y == v.y) 86 st.insert({v.x,v.y}); 87 } 88 } 89 ans -= st.size(); 90 } 91 cout << ans << endl; 92 return 0; 93 }