11768 - Lattice Point or Not

题目中给的点都是0.1的倍数, 要求两个点之间整数点的个数, 一个很自然的想法是把坐标都乘以10, 然后找第一个整十倍点(x1,y1)和最后一个整十倍点(x2,y2), 那么答案就是:

     gcd(abs(x1 / 10 - x2 / 10), abs(y1 / 10 - y2 / 10)) + 1;

但是怎么找10倍点的个数呢, 按照x增1的方式枚举肯定不行,因为我试过了, 超时的, 因为整点之间的距离总是相等的, 可以按照相邻两个整点之间的位置向量开始枚举, 实验证明速度还不错。

View Code
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<algorithm>
  5 using namespace std;
  6 
  7 const double eps = 1e-9;
  8 
  9 bool between(int a, int x, int y) {
 10     if(x <= y) {
 11         if(a >= x && a <= y) return true;
 12         return false;
 13     }
 14     if(x >= y) {
 15         if(a >= y && a <= x) return true;
 16         return false;
 17     }
 18 }
 19 int gcd(int a, int b) {
 20     return b ? gcd(b, a % b) : a;
 21 }
 22 int main() {
 23     int T;
 24     cin >> T;
 25     while(T--) {
 26         double x1, y1, x2, y2;
 27         int a, b, c, d;
 28         cin >> x1 >> y1 >> x2 >> y2;
 29         a = (int)(x1 * 10 + eps);
 30         b = (int)(y1 * 10 + eps);
 31         c = (int)(x2 * 10 + eps);
 32         d = (int)(y2 * 10 + eps);
 33         if(a > c) {
 34             swap(a, c);
 35             swap(b, d);
 36         }
 37         if(c == a) {
 38             if(c % 10) {
 39                 cout << 0 << endl;
 40                 continue;
 41             }
 42             if(b > d) swap(b, d);
 43             int yy1 = -1, yy2 = -1;
 44             for(int i = b; i <= d; ++i) {
 45                 if(i % 10 == 0) {
 46                     yy1 = i;
 47                     break;
 48                 }
 49             }
 50             for(int i = d; i >= b; --i) {
 51                 if(i % 10 == 0) {
 52                     yy2 = i;
 53                     break;
 54                 }
 55             }
 56             if(yy1 == -1 || yy2 == -1) {
 57                 cout << 0 << endl;
 58                 continue;
 59             }
 60             cout << yy2 / 10 - yy1 / 10 + 1 << endl;
 61             continue;
 62         }
 63         int cnt = gcd(abs(a - c), abs(b - d));
 64         int xx = (c - a) / cnt;
 65         int yy = (d - b) / cnt;
 66         int ans = 0;
 67         int xx1 = -1, yy1 =  -1;
 68         int y = b;
 69         for(int  i = a; i <= c; i += xx, y += yy) {
 70             if(i % 10 == 0) {
 71 //                int y = (d - b) * (c - i);
 72 //                if(y % (c - a) != 0) continue;
 73 //                if(y % (c - a) != 0) break;
 74 //                y = d - y / (c - a);
 75                 
 76                 if(between(y, b, d) && y % 10 == 0) {
 77                     xx1 = i;
 78                     yy1 = y;
 79                     break;
 80                 }
 81             }
 82         }
 83         int xx2 = -1, yy2 = -1;
 84         y = d;
 85         for(int  i = c; i >= a; i -= xx, y -= yy) {
 86             if(i % 10 == 0) {
 87             //    int y = (d - b) * (c - i);
 88         //        if(y % (c - a) != 0) continue;
 89             //    if(y % (c - a) != 0) break;
 90             //    y = d - y / (c - a);
 91                 if(between(y, b, d) && y % 10 == 0) {
 92                     xx2 = i;
 93                     yy2 = y;
 94                     break;
 95                 }
 96             }
 97         }
 98         if(xx1 == -1 || xx2 == -1) cout << 0 << endl;
 99         else
100             cout << gcd(abs(xx1 / 10 - xx2 / 10), abs(yy1 / 10 - yy2 / 10)) + 1 << endl;
101     }
102     return 0;
103 }

 

posted @ 2013-01-29 20:03  ACSeed  Views(154)  Comments(0)    收藏  举报