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.
The first line contains three integers n, x0 и 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 xi, yi ( - 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.
Print a single integer — the minimum number of shots Han Solo needs to destroy all the stormtroopers.
4 0 0 1 1 2 2 2 0 -1 -1
2
2 1 2 1 1 1 0
1
Explanation to the first and second samples from the statement, respectively:

思路:刚开始我用的向量做得,一个一个暴力算出角度,看向量是否平行,平行的话就不要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;
}
本文探讨了在战斗场上,使用最新双管激光枪击溃众多帝国士兵的最有效方式。通过数学分析和几何理解,文章揭示了如何仅用最少的射击次数实现目标。详细介绍了输入参数的含义、解决方案的步骤以及实例解析。
240

被折叠的 条评论
为什么被折叠?



