Codeforces Round 1009 (Div. 3)
A. Draw a Square
题目大意
给你(-l,0)、(r,0)、(0,-d)、(0,u)四个坐标,问是不是一个正方形
解题思路
都相等就是正方形
代码实现
#include <bits/stdc++.h>
using i64 = long long;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int tt;
std::cin >> tt;
while (tt--) {
int l, r, d, u;
std::cin >> l >> r >> d >> u;
std::set<int> st = {l, r, d, u};
if (st.size() == 1) {
std::cout << "Yes\n";
} else {
std::cout << "No\n";
}
}
}
B. The Third Side
题目大意
给你一个数组a,选择其中两个元素删除,再加入一个元素满足它和被删除的元素能构成一个三角形,问a最后一个元素的最大值
解题思路
显然每次新加的元素都是最大边,它的值是被删除元素之和-1,共计执行n-1次操作
代码实现
#include <bits/stdc++.h>
using i64 = long long;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int tt;
std::cin >> tt;
while (tt--) {
int n;
std::cin >> n;
std::vector<int> a(n);
for (int i = 0; i < n; i++) {
std::cin >> a[i];
}
std::cout << std::accumulate(a.begin(), a.end(), -n + 1ll) << "\n";
}
}
C. XOR and Triangle
题目大意
给你一个x,找到一个y满足y小于x并且让x,y,x^y(称其为z)能构成三角形,找不到输出-1
解题思路
让y把x的高位之后全部填1就能让异或之后的z得到和x相同的高位,之后再加上y的所有低位1一定会比x大,这种情况下如果存在一定会满足,检查能否构成三角形即可
代码实现
#include <bits/stdc++.h>
using i64 = long long;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int tt;
std::cin >> tt;
while (tt--) {
int x;
std::cin >> x;
int y = (1 << std::__lg(x)) - 1;
int z = x ^ y;
if (y >= 1 && z >= 1 && x + y > z && y + z > x) {
std::cout << y << "\n";
} else {
std::cout << -1 << "\n";
}
}
}
D. Counting Points
题目大意
给你n个圆心在x轴上的圆和半径(半径和为m),问有多少个整数点在这些圆内
解题思路
发现m的范围比较小,因此可以从m入手,暴力检查所有的半径范围,查看当前这个x对应的最大y是多少,离散化之后对每个位置的最大y求和即可
代码实现
#include <bits/stdc++.h>
using i64 = long long;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int tt;
std::cin >> tt;
while (tt--) {
int n, m;
std::cin >> n >> m;
std::vector<i64> x(n), r(n);
std::map<i64, i64> mp;
for (int i = 0; i < n; i++) {
std::cin >> x[i];
}
for (int i = 0; i < n; i++) {
std::cin >> r[i];
}
for (int i = 0; i < n; i++) {
for (int j = x[i] - r[i]; j <= x[i] + r[i]; j++) {
mp[j] = std::max(mp[j], (i64)std::sqrt(r[i] * r[i] - (x[i] - j) * (x[i] - j)));
}
}
i64 ans = 0;
for (auto [x, y] : mp) {
ans += y * 2 + 1;
}
std::cout << ans << "\n";
}
}
E. Empty Triangle
题目大意
交互题,每次可以询问三个索引,表示本次询问的点集的索引,如果三点构成的三角形内部有其他的点,会回答三角形内部任意一个点的索引,如果没有回答0,用不超过75次询问选择找到一个一组三角形内部没有其他点
解题思路
随机数乱搞,证明
代码实现
#include <bits/stdc++.h>
using i64 = long long;
std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count());
int main() {
int tt;
std::cin >> tt;
while (tt--) {
int n;
std::cin >> n;
int a = 1, b = 2, c = 3;
while (1) {
std::cout << "?" << " " << a << " " << b << " " << c << std::endl;
int p = std::uniform_int_distribution<int>(0, 3)(rng), idx;
std::cin >> idx;
if (idx == 0) {
std::cout << "!" << " " << a << " " << b << " " << c << std::endl;
break;
}
if (p == 0) {
a = idx;
} else if (p == 1) {
b = idx;
} else {
c = idx;
}
}
}
}
F. Counting Necessary Nodes
题目大意
题目没懂
解题思路
代码抄的
代码实现
#include <bits/stdc++.h>
using i64 = long long;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int tt;
std::cin >> tt;
while (tt--) {
i64 l1, r1, l2, r2;
std::cin >> l1 >> r1 >> l2 >> r2;
std::vector<i64> a(32);
for (int k = 0; k <= 30; k++) {
i64 bit = 1ll << k;
i64 x = std::max(0ll, r1 / bit - (l1 + bit - 1) / bit);
i64 y = std::max(0ll, r2 / bit - (l2 + bit - 1) / bit);
a[k] = x * y;
}
i64 ans = 0;
for (int k = 0; k <= 30; k++) {
ans += a[k] - 4 * a[k + 1];
}
std::cout << ans << "\n";
}
}
G. Game With Triangles: Season 2
题目大意
给你一个正n边形,每个顶点上有一个正整数,要求选择若干个不相交的三角形,使得这些三角形的顶点值乘积之和最大
解题思路
区间dp,先复制一次数组破坏为链,然后考虑lr区间里选择第三个点得到最优解或者最优解来自lr里的两个区间即可
代码实现
#include <bits/stdc++.h>
using i64 = long long;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int tt;
std::cin >> tt;
while (tt--) {
int n;
std::cin >> n;
std::vector<int> a(2 * n + 1);
for (int i = 1; i <= n; i++) {
std::cin >> a[i];
a[i + n] = a[i];
}
std::vector<std::vector<i64>> dp(2 * n + 1, std::vector<i64>(2 * n + 1));
for (int len = 3; len <= n; len++) {
for (int l = 1; l + len - 1 <= 2 * n; l++) {
int r = l + len - 1;
for (int k = l; k < r; k++) {
dp[l][r] = std::max(dp[l][r], dp[l][k] + dp[k + 1][r]);
if (k > l) {
dp[l][r] = std::max(dp[l][r], a[l] * a[r] * a[k] + dp[l + 1][k - 1] + dp[k + 1][r - 1]);
}
}
}
}
i64 ans = 0;
for (int i = 1; i <= n; i++) {
ans = std::max(ans, dp[i][i + n - 1]);
}
std::cout << ans << "\n";
}
}

浙公网安备 33010602011771号