A. Draw a Square
题意:\(4\)个点,两个在\(x\)轴上,两个在\(y\)轴上,求它们能不能形成正方形。
显然它们离原点的距离都要相同。
点击查看代码
void solve() {int l, r, d, u;std::cin >> l >> r >> d >> u;if (l == r && d == u && l == d) {std::cout << "YES\n";} else {std::cout << "NO\n";}
}
B. The Third Side
题意:给你一个数组,每次选其中两个数和一个\(x\),使得这三个数可以组成三角形。然后删除选出的两个数,把\(x\)加进去。
从大到小排序,然后每次拿两个最大处理,\(x\)取值取最大。
点击查看代码
void solve() {int n;std::cin >> n;std::vector<int> a(n);for (int i = 0; i < n; ++ i) {std::cin >> a[i];}i64 ans = a[n - 1];for (int i = n - 2; i >= 0; -- i) {ans = ans + a[i] - 1;}std::cout << ans << "\n";
}
C. XOR and Triangle
题意:给你\(x\),求一个\(y\)使得\(y < x\)且\(x \oplus y, x, y\)可以组成三角形。
设\(x\)最高位\(1\)为\(i\),那么使得\(y = 2^i - 1\)即可。
点击查看代码
void solve() {int x;std::cin >> x;int y = 0;for (int i = 30, flag = 0; i >= 0; -- i) {if (~x >> i & 1) {if (flag) {y += 1 << i;}} else {if (flag) {y += 1 << i;}flag = 1;}}int z = (x ^ y);if (y >= x || x + y <= z || y + z <= x || x + z <= y) {std::cout << -1 << "\n";} else {std::cout << y << "\n";}
}
D. Counting Points
题意:给出\(n\)个圆心在\(x\)轴上的\(n\)个圆,它们半径之和为\(m\)。求有多少整数点被至少一个圆包含。
对于\(x\)轴上的点来说,如果他被一个圆包含了,那么它上面和下面各有\(\sqrt(r_i ^ 2 - (i - x_i)^2)\)个点也被包含了。那么对于每个圆暴力枚举\(x\)轴上每个被它包含的点,然后每个记录往上下一样包含的点最大值。用\(map\)存。
点击查看代码
void solve() {int n, m;std::cin >> n >> m;std::vector<i64> x(n), r(n);for (int i = 0; i < n; ++ i) {std::cin >> x[i];}for (int i = 0; i < n; ++ i) {std::cin >> r[i];}std::map<i64, i64> mp;for (int i = 0; i < n; ++ i) {i64 L = x[i] - r[i], R = x[i] + r[i];while (L <= R) {i64 h = std::sqrt(r[i] * r[i] - (R - x[i]) * (R - x[i]));mp[L] = std::max(mp[L], h + 1);mp[R] = std::max(mp[R], h + 1);++ L;-- R;}}i64 ans = 0;for (auto & [x, y] : mp) {ans += y * 2 - 1;}std::cout << ans << "\n";
}
E. Empty Triangle
题意:交互题。有\(n\)个点,你每次问三个点,会回答你被它们组成的三角形包含的某个点下标,如果没有则回答\(0\)。不超过\(75\)次询问找出三个点,它们组成的三角形不包含其它任何点。
乱搞搞过去的。
点击查看代码
int ask(int i, int j, int k) {std::cout << "? " << i << " " << j << " " << k << std::endl;int res;std::cin >> res;return res;
}void solve() {int n;std::cin >> n;int i = 1, j = (n + 1) / 2, k = n;while (1) {int p = ask(i, j, k);if (p == 0) {std::cout << "! " << i << " " << j << " " << k << std::endl;return;}if (p & 1) {i = j;j = k;k = p; } else {k = j;j = i;i = p;}}
}
F. Counting Necessary Nodes
没看懂题。
待补
G. Game With Triangles: Season 2
题意:\(n\)个点围成一个多边形,你每次选三个点获得\(a_i \times a_j \times a_k\)的贡献,所有选出的三个点构成的三角形不能有交集,每个点只能选一次。求最大价值。
区间\(dp\)。考虑破环成链,把数组复制一份。然后\(f[i][j]\)表示从\(i\)到\(j\)个点的最大贡献。那么首先\(f[i][j] = \max(f[i + 1][j], f[i + 1][j], f[i][j - 1])\)。表示不选\(i\)或者不选\(j\)或者都不选。然后枚举和\(i, j\)组成三角形的点\(k\), \(f[i][j] = \max(f[i][j], a_i \times a_j \times a_k + f[i + 1][k - 1] + f[k + 1][j - 1])\)。同时也可以不用\(i, j\),枚举\(k\)作为分界点,\(f[i][j] = \max(f[i][j], f[i][k] + f[k + 1][j], f[i][k - 1] + f[k][j])\)。
点击查看代码
void solve() {int n;std::cin >> n;std::vector<i64> a(2 * n + 1);for (int i = 1; i <= n; ++ i) {std::cin >> a[i];a[i + n] = a[i];}std::vector f(2 * n + 1, std::vector<i64>(2 * n + 1));for (int len = 3; len <= n; ++ len) {for (int i = 1; i + len - 1 <= 2 * n; ++ i) {int j = i + len - 1;f[i][j] = std::max({f[i + 1][j], f[i][j - 1], f[i + 1][j - 1]});for (int k = i + 1; k < j; ++ k) {f[i][j] = std::max(f[i][j], a[i] * a[j] * a[k] + f[i + 1][k - 1] + f[k + 1][j - 1]);f[i][j] = std::max({f[i][j], f[i][k] + f[k + 1][j], f[i][k - 1] + f[k][j]});}}}i64 ans = 0;for (int i = 1; i <= n; ++ i) {ans = std::max(ans, f[i][i + n - 1]);}std::cout << ans << "\n";
}