Codeforces Round #291 (Div. 2) -- B. Han Solo and Lazer Gun (计算几何~暴力)

B. Han Solo and Lazer Gun
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

There are n Imperial stormtroopers on the field. The battle field is a plane with Cartesian coordinate system. Each stormtrooper is associated with his coordinates (x, y) on this plane.

Han Solo has the newest duplex lazer gun to fight these stormtroopers. It is situated at the point (x0, y0). In one shot it can can destroy all the stormtroopers, situated on some line that crosses point (x0, y0).

Your task is to determine what minimum number of shots Han Solo needs to defeat all the stormtroopers.

The gun is the newest invention, it shoots very quickly and even after a very large number of shots the stormtroopers don't have enough time to realize what's happening and change their location.

Input

The first line contains three integers nx0 и y0 (1 ≤ n ≤ 1000 - 104 ≤ x0, y0 ≤ 104) — the number of stormtroopers on the battle field and the coordinates of your gun.

Next n lines contain two integers each xiyi ( - 104 ≤ xi, yi ≤ 104) — the coordinates of the stormtroopers on the battlefield. It is guaranteed that no stormtrooper stands at the same point with the gun. Multiple stormtroopers can stand at the same point.

Output

Print a single integer — the minimum number of shots Han Solo needs to destroy all the stormtroopers.

Sample test(s)
input
4 0 0
1 1
2 2
2 0
-1 -1
output
2
input
2 1 2
1 1
1 0
output
1
Note

Explanation to the first and second samples from the statement, respectively:

Codeforces Round #291 (Div. 2) -- B. Han Solo and Lazer Gun (计算几何~暴力)_第1张图片






思路:刚开始我用的向量做得,一个一个暴力算出角度,看向量是否平行,平行的话就不要ans++,然后,,就这样WA了╮(╯_╰)╭,其实最好不要用向量做,因为存在浮点数误差,算着算着不知名的错误就来了,除了直接算角度,还可以用求最大公约数来求同一直线上的点(用一个点代表直线上的点,因为都是整数,所以如果在同一直线上就会有公共向量,都除以其最大公约数就可以求得公共向量,还有在x,y轴上的公共向量可以用(1,0)(0,1)表示。。公共向量可以用set存储)


AC代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <set>
using namespace std;

int gcd(int a, int b) {		//求最大公约数 
	if(a > b) return gcd(b, a);
	if(b % a == 0) return a;
	return gcd(b % a, a);
}

int main() {
	int n, x, y;
	set<pair<int, int> > a;
	while(scanf("%d %d %d", &n, &x, &y) != EOF) {
		for(int i = 0; i < n; i++) {
			int p, q;
			scanf("%d %d", &p, &q);
			p -= x, q -= y;
			if(p == 0) a.insert(make_pair(0, 1));
			else if(q == 0) a.insert(make_pair(1, 0));
			else 
			{
				int t = gcd(abs(p), abs(q));
				p /= t;
				q /= t;
				if(p < 0) { p = -p; q = -q; }
				a.insert(make_pair(p, q));
			}
		}
		printf("%d\n", a.size());
	}
	return 0;
} 








最开始套模板做得,,╮(╯▽╰)╭


贴一下蛋疼的代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;

const double PI = 4 * atan(1.0);

struct Point {
	double x, y;
	Point(double x = 0, double y = 0) : x(x) , y(y) { }  
};

typedef Point Vector;  

Vector operator + (Vector A, Vector B) { return Vector(A.x+B.x, A.y+B.y); }
Vector operator - (Vector A, Vector B) { return Vector(A.x-B.x, A.y-B.y); }
Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); }
Vector operator / (Vector A, double p) { return Vector(A.x/p, A.y/p); } 

bool operator < (const Point& a, const Point& b) {
	return a.x < b.x || (a.x == b.x && a.y < b.y);
} 

const double eps = 1e-9;
int dcmp(double x) {
	if(fabs(x) < eps) return 0; else return x < 0 ? -1 : 1;
}

bool operator == (const Point& a, const Point& b) {
	return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
}

double Dot(Vector A, Vector B) { return A.x*B.x + A.y*B.y; } 
double Length(Vector A) { return sqrt(Dot(A, A)); }		
double Angle(Vector A, Vector B) { return acos(Dot(A, B) / Length(A) / Length(B)); } 

double Cross(Vector A, Vector B) { return A.x*B.y - A.y*B.x; }
double Area2(Point A, Point B, Point C) { return Cross(B-A, C-A); }

Vector Rotate(Vector A, double rad) {
	return Vector(A.x*cos(rad) - A.y*sin(rad), A.x*sin(rad)+A.y*cos(rad) );
} 

Vector Normal(Vector A) {  
    double L = Length(A);  
    return Vector(-A.y/L, A.x/L);  
}

Point GetLineIntersection(Point P, Vector v, Point Q, Vector w) {
	Vector u = P - Q;
	double t = Cross(w, u) / Cross(v, w);
	return P + v * t;
} 
 
double DistanceToLine(Point P, Point A, Point B) {  
    Vector v1 = B-A, v2 = P - A;  
    return fabs(Cross(v1,v2) / Length(v1)); 
}  

double DistanceToSegment(Point P, Point A, Point B) {  
    if(A==B) return Length(P-A);  
    Vector v1 = B - A, v2 = P - A, v3 = P - B;  
    if(dcmp(Dot(v1, v2)) < 0) return Length(v2);  
    else if(dcmp(Dot(v1, v3)) > 0) return Length(v3);  
    else return fabs(Cross(v1, v2)) / Length(v1);  
}  

Point GetLineProjection(Point P, Point A, Point B) {
	Vector v = B - A;
	return A + v * ( Dot(v, P-A) / Dot(v, v) ); 
}  

bool SegmentProperIntersection(Point a1, Point a2, Point b1, Point b2) {
	double c1 = Cross(a2 - a1, b1 - a1), c2 = Cross(a2 - a1, b2 - a1),
			c3 = Cross(b2 - b1, a1 - b1), c4 = Cross(b2 - b1, a2 - b1);
	return dcmp(c1) * dcmp(c2) < 0 && dcmp(c3) * dcmp(c4) < 0;
} 

bool OnSegment(Point p, Point a1, Point a2) {
	return dcmp(Cross(a1 - p, a2 - p)) == 0 && dcmp(Dot(a1 - p, a2 - p)) < 0;
} 

double ConvexPolygonArea(Point* p, int n) {  
    double area = 0;  
    for(int i = 1; i < n-1; i++)  
        area += Cross(p[i] - p[0], p[i + 1] - p[0]);  
    return area / 2;  
}  

int main() {
	Point A, B[1005];
	Vector V[1005];
	int n;
	while(scanf("%d %lf %lf", &n, &A.x, &A.y) != EOF) {
		for(int i = 0; i < n; i++) {
			scanf("%lf %lf", &B[i].x, &B[i].y);
			V[i] = B[i] - A;
		}
		
		int ans = n, i, j;
		for(i = 1; i < n; i++) { 
			for(j = 0; j < i; j++) {
				if( fabs(fabs(Angle(V[i], V[j]) ) - PI) < eps || fabs(fabs(Angle(V[i], V[j])) - 0) < eps)
				{ ans--; break; }
			}
		}
		printf("%d\n", ans);
	}
	return 0;
} 






你可能感兴趣的:(ACM,codeforces,计算几何)