这是我人生中的第一个计算几何题,好好收藏一下。
1、当一个点关于远点对称之后,除了两点之间的连线外,其他的任何直线都会讲两点分成两个部分
2、极角排序
3、线的旋转
4、叉积求 sin
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> using namespace std; class Node { public: int x,y,color; double rad; bool operator < (const Node& rhs) const { return rad < rhs.rad; } }a[1010],p[1010]; // Turn 表示叉积求sin 即 不能超过180 bool Turn(Node& a,Node& b) { return a.x * b.y >= a.y * b.x; } int main () { int N; //freopen("1.txt","r",stdin); while (cin >> N, N) { for (int i = 0;i < N;i++) { cin >> a[i].x >> a[i].y >> a[i].color; } if (N <= 2) { cout << N << endl; continue; } int maxn = 0; for (int i = 0;i < N;i++) { int k = 0; for (int j = 0;j < N;j++) { if (i != j) { p[k].x = a[j].x - a[i].x; p[k].y = a[j].y - a[i].y; if (a[j].color) { // 原点对称 p[k].x = -p[k].x; p[k].y = -p[k].y; } p[k].rad = atan2(p[k].y,p[k].x); // 求弧度 k++; } } sort(p,p + k); // 极角排序 int L = 0;int ans = 1; int R = 0; while (L < k) { if (L == R) { R = (R + 1) % k; ans ++; } while (L != R && Turn(p[L],p[R])) { // 不能转过180度 L!=R 是考虑到 如果转过180 回到起始点 ans++; R = (R + 1) % k; } maxn = max(maxn,ans); L++; ans--; } } cout << maxn << endl; } }
时间: 2024-10-11 20:51:22