NC206190. 兰德索尔的瞭望塔
描述
输入描述
每个测试点包含多组数据,请处理到文件结束。
每组测试数据的第一行有两个整数 和,表示骑士们选定的候选点个数,以及军营所处位置 的坐标。
接下来有 行,每一行包含两个整数 ,表示第 个候选点的位置。保证单个测试点的所有测试数据中,候选点的个数之和 。
保证所有的坐标数据()都在 int 的范围之内,且任意两个点不重复。
输出描述
对于每组测试数据,在单独的一行内输出一个整数,表示所给的 个点中,满足修筑包含关系的最多的一组点。
示例1
输入:
2 4 2 1 4 2 3 4 2 2 2 3 1 3 5 4 2 1 4 2 2 2 1 2 2 3 5 5 1 1 2 2 3 3 4 4 5 5
输出:
1 2 3 1
说明:
输入样例包含四组测试数据。C++14(g++5.4) 解法, 执行用时: 315ms, 内存消耗: 13656K, 提交时间: 2020-05-18 22:03:03
#include <bits/stdc++.h> using namespace std; #ifndef ONLINE_JUDGE #define debug(x) cout << #x << ": " << x << endl #else #define debug(x) #endif typedef long long ll; const int maxn = 2e5 + 5; struct Point { int x, y; Point() : x(0), y(0) {} Point(int _x, int _y) : x(_x), y(_y) {} Point operator-(const Point& o) const { return Point(x - o.x, y - o.y); } void get_in() { scanf("%d%d", &x, &y); } } P[maxn]; bool cmp_1(Point A, Point B) { ll tmp_1 = 1LL * A.y * B.x; ll tmp_2 = 1LL * A.x * B.y; return tmp_1 > tmp_2; } bool cmp_2(Point A, Point B) { ll tmp_1 = 1LL * A.y * B.x; ll tmp_2 = 1LL * A.x * B.y; return tmp_1 < tmp_2; } int N, X, mx, dp[maxn]; Point Sta[maxn], Base_A; int find(Point A) { int l = 1, r = mx, res = 0; A = Base_A - A; while (l <= r) { int mid = (l + r) >> 1; if (cmp_1(A, Sta[mid])) res = mid, l = mid + 1; else r = mid - 1; } return res; } int main() { while (~scanf("%d%d", &N, &X)) { Base_A = Point(X, 0); for (int i = 1; i <= N; i++) P[i].get_in(); sort(P + 1, P + N + 1, cmp_1), mx = 0; for (int i = 1; i <= N; i++) { Sta[dp[i] = find(P[i]) + 1] = Base_A - P[i]; if (dp[i] > mx) mx = dp[i]; } printf("%d\n", mx); } return 0; }
C++11(clang++ 3.9) 解法, 执行用时: 248ms, 内存消耗: 2784K, 提交时间: 2020-05-17 17:32:27
#include <bits/stdc++.h> using namespace std; typedef long long LL; int read() { int res = 0, f = 1; char c = getchar(); while(!isdigit(c) && c != '-') c = getchar(); if(c == '-') f = -1, c = getchar(); while(isdigit(c)) res = (res<<3)+(res<<1)+(c^48), c = getchar(); return res*f; } const double pi = acos(-1); const int maxn = 1e5+10; int n, X; struct Node { double x, y; bool operator < (const Node &u) const { return x < u.x || x == u.x && (y > u.y); } } a[maxn]; double b[maxn]; int cnt; int main() { while(~scanf("%d%d", &n, &X)) { for(int i = 1; i <= n; i++) { int u = read(), v = read(); if(X > u) a[i] = {atan(1.0*v/u), atan(1.0*v/(X-u))}; else if(X == u) a[i] = {atan(1.0*v/u), pi/2}; else a[i] = {atan(1.0*v/u), atan(1.0*v/(X-u))+pi}; } sort(a+1, a+n+1); cnt = 0; memset(b, 0, sizeof(double)*(n+5)); for(int i = 1; i <= n; i++) { double now = a[i].y; int p = lower_bound(b+1, b+cnt+1, now)-b; b[p] = now; if(p > cnt) cnt++; } printf("%d\n", cnt); } return 0; } /* 3 1 1 1 2 3 2 4 */