题目很水。睡过了迟到了一个小时,到达战场一看,俩队友AC五个了。。
就只贴我补的几个吧。
B - Breaking Biscuits Gym - 101606B
旋转卡壳模板题。然后敲错了。
代码是另一种做法:对于每条边,枚举两边的所有点到直线的距离,分别取最大值,然后加起来。
#include <bits/stdc++.h> #define FOPI freopen("in.txt", "r", stdin); #define FOPO freopen("out.txt", "w", stdout); using namespace std; typedef long long LL; const double esp = 1e-8; const int maxn = 100 + 10; struct Point { double x, y; Point() {} Point(double _x, double _y) { x = _x, y = _y; } Point operator - (const Point &b) const { return Point(x-b.x, y-b.y); } double operator * (const Point &b) const { return x*b.x + y*b.y; } double length() { return hypot(x, y); } }; typedef Point Vector; double cross(Vector a, Vector b) { return a.x*b.y - a.y*b.x; } double dist(Point p, Point a, Point b) { return cross(p-a, b-a) / (b-a).length(); } Point a[maxn]; int n; int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%lf%lf", &a[i].x, &a[i].y); double ans = 1e50; for (int i = 1; i <= n; i++) for (int j = i+1; j <= n; j++) { double left = 1e50, right = -1e50; for (int k = 1; k <= n; k++) { left = min(left, dist(a[k], a[i], a[j])); right = max(right, dist(a[k], a[i], a[j])); } ans = min(ans, right-left); } printf("%.7f ", ans); }
F - Flipping Coins Gym - 101606F
dp[i][j] 表示 翻了 j 次后,有 i 个正面朝上的概率。
每次翻面一定优先翻反面朝上的硬币。
那么dp[i][j]的概率可以更新 dp[i+1][j+1] 和 dp[i]j+1]。
特别的,对于 i == n, dp[i][j] 更新的是dp[i-1][j+1] 和 dp[i][j+1]
#include <bits/stdc++.h> using namespace std; const int maxn = 400 + 100; int n, k; double dp[maxn][maxn]; int main() { scanf("%d%d", &n, &k); dp[0][0] = 1; for (int j = 0; j < k; j++) for (int i = 0; i <= n; i++) { if (i == n) { dp[i-1][j+1] += 0.5*dp[i][j]; dp[i][j+1] += 0.5*dp[i][j]; } else { dp[i+1][j+1] += 0.5*dp[i][j]; dp[i][j+1] += 0.5*dp[i][j]; } } double ans = 0; for (int i = 0; i <= n; i++) ans += dp[i][k] * i; printf("%.7f ", ans); }
L - Lizard Lounge Gym - 101606L
对于每一个人求出他和中点的斜率来,然后约分后分类,分别求LIS。
WA了一次是因为求成最长不降升子序列了。估计场上急眼了的话不好查错。
pair还是很好用的。
#include <bits/stdc++.h> #define FOPI freopen("in.txt", "r", stdin); #define FOPO freopen("out.txt", "w", stdout); using namespace std; typedef long long LL; const int maxn = 1e6 + 100; typedef pair<int, int> prInt; typedef pair<double, int> prDouble; int sx, sy; int n; int x[maxn], y[maxn]; int k[maxn]; map<prInt, int> M; vector<prDouble> a[maxn]; int LIS(vector<prDouble> &a) { int tot = 0; for (int i = 0; i < a.size(); i++) { int l = 1, r = tot, x = -1; while(l <= r) { int mid = (l+r)/2; if (k[mid] >= a[i].second) x = mid, r = mid-1; else l = mid+1; } if (x == -1) x = ++tot; k[x] = a[i].second; } return tot; } int main() { scanf("%d%d", &sx, &sy); scanf("%d", &n); int cnt = 0; for (int i = 1; i <= n; i++) { int x, y, h; scanf("%d%d%d", &x, &y, &h); x -= sx, y -= sy; int g = __gcd(abs(x), abs(y)); prInt p = prInt(x/g, y/g); if (!M.count(p)) M[p] = ++cnt; a[M[p]].push_back(prDouble(hypot(x, y), h)); } int ans = 0; for (int i = 1; i <= cnt; i++) { sort(a[i].begin(), a[i].end()); ans += LIS(a[i]); } printf("%d ", ans); }