思路一
考虑到数据范围比较小,我们考虑尝试 $\mathcal{O}(n^3)$ 的做法,枚举两个点确定一条线段,然后枚举第三个点,用外积判断三角形的面积是否 $0$,如果外积为 $0$ ,则说明该点在直线上,在洛谷上提交时,如果 $k$ 不从 $j+1$ 开始循环会 $tle$ 三个点,如果不开 $o2$ 优化会 $tle$ 一个点。
代码
1 2 3 4
| #include <bits/stdc++.h> #define FOR(i,f_start,f_end) for(int i=f_start;i<=f_end;++i) #define pb push_back using namespace std;
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| typedef long long ll; typedef unsigned long long ull; typedef pair<int,int>PII; const double eps = 1e-8; const int maxn = 200000 + 5; const int inf = 0x3f3f3f3f; const int mod = 1e9+7;
typedef pair<double,double> PDD; #define x first #define y second PDD q[maxn];
PDD operator-(PDD a,PDD b){ return {a.x-b.x,a.y-b.y}; }
double cross(PDD a,PDD b){ return a.x*b.y - a.y*b.x; }
double area(PDD a,PDD b,PDD c){ return cross(b-a,c-a); }
int sign(double x){ if(fabs(x) < eps){ return 0; }else if(x < 0) return -1; else return 1; }
int main(){
int ans = 2; int n; cin >> n; for(int i=1;i<=n;i++){ cin >> q[i].x >> q[i].y; } for(int i=1;i<=n;i++){ for(int j=i+1;j<=n;j++){ int now = 2; for(int k=1;k<=n;k++){ if(k == i || k == j) continue; else if(!sign(area(q[i],q[j],q[k]))){ now++; } } ans = max(ans,now); } } cout << ans << endl; return 0; }
|
思路二
我们考虑枚举每一个起点,计算其余所有点和这条直线的斜率,然后对斜率进行排序,如果斜率相同则说明在一条直线上,即为判断直线的角度相同或者相差 $180^{\circ}$。我们将所有直线计算角度,如果大于 $180^{\circ}$ 则减去 $\pi$ 时间复杂度为 $\mathcal{O}(n^2\log{n})$
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| #include <bits/stdc++.h> #define FOR(i,f_start,f_end) for(int i=f_start;i<=f_end;++i) #define pb push_back using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int>PII; const double eps = 1e-8; const int maxn = 200000 + 5; const int inf = 0x3f3f3f3f; const int mod = 1e9+7;
typedef pair<double,double> PDD; const double pi = acos(-1); struct Line { PDD st,ed; }line[maxn]; double angle[maxn]; PDD q[maxn];
#define x first #define y second
double get_angle(PDD a,PDD b){ double k = atan2(a.y - b.y,a.x - b.x); if(k > pi) return k-pi; else return k; }
bool cmp(Line a,Line b){ double A = get_angle(a.st,a.ed),B = get_angle(b.st,a.ed); }
int dcmp(double a,double b){ if(fabs(a-b) < eps) return 0; else if(a < b) return -1; else return 1; }
int main(){
int n; cin >> n; for(int i=1;i<=n;i++){ cin >> q[i].x >> q[i].y; } int ans = 0; for(int i=1;i<=n;i++){ int cnt = 0; for(int j=1;j<=n;j++){ if(j == i) continue; angle[cnt++] = get_angle(q[j],q[i]); } sort(angle,angle+cnt); int tmp = 2; for(int j=1;j<cnt;j++){ if(!dcmp(angle[j-1],angle[j])) tmp++; else tmp = 2; ans = max(ans,tmp); } } cout << ans << endl; return 0; }
|