A. ABC400 Party
模拟
代码实现
a = int(input())
b, r = divmod(400, a)
print(b if r == 0 else -1)
B. Sum of Geometric Series
模拟
代码实现
n, m = map(int, input().split())
ans = sum(n**i for i in range(m+1))
if ans > 10**9:
ans = 'inf'
print(ans)
C. 2^a b^2
\(a < 60\),\(b < 10^9\)
只需考虑 \(b\) 为奇数的情况就可以避免重复。然后,通过枚举 \(a\) 并计算 \(b\) 的候选数量即可!还需注意 sqrt 的误差
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
int main() {
ll n;
cin >> n;
ll ans = 0;
for (int a = 1; a < 60; ++a) {
ll x = n;
rep(i, a) x /= 2;
ll m = sqrtl(x);
ans += (m+1)/2;
}
cout << ans << '\n';
return 0;
}
D. Takahashi the Wall Breaker
01bfs
这是一个最短路问题,其中普通上下左右移动的费用为 \(0\),而跨一堵或两堵墙移动的费用为 \(1\)
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
const int di[] = {-1, 0, 1, 0};
const int dj[] = {0, 1, 0, -1};
int main() {
int h, w;
cin >> h >> w;
vector<string> s(h);
rep(i, h) cin >> s[i];
int si, sj, ti, tj;
cin >> si >> sj >> ti >> tj;
--si; --sj; --ti; --tj;
const int INF = 1001001001;
vector dist(h, vector<int>(w, INF));
vector used(h, vector<bool>(w));
deque<pair<int, int>> q;
auto push = [&](int i, int j, int d, int cost) {
if (dist[i][j] <= d) return;
dist[i][j] = d;
if (cost == 0) q.emplace_front(i, j);
else q.emplace_back(i, j);
};
push(si, sj, 0, 0);
while (q.size()) {
auto [i, j] = q.front(); q.pop_front();
if (used[i][j]) continue;
used[i][j] = true;
int d = dist[i][j];
rep(v, 4) {
int ni = i+di[v], nj = j+dj[v];
if (ni < 0 or nj < 0 or ni >= h or nj >= w) continue;
if (s[ni][nj] == '.') push(ni, nj, d, 0);
}
rep(v, 4) {
int ni = i, nj = j;
rep(k, 2) {
ni += di[v], nj += dj[v];
if (ni < 0 or nj < 0 or ni >= h or nj >= w) break;
push(ni, nj, d+1, 1);
}
}
}
int ans = dist[ti][tj];
cout << ans << '\n';
return 0;
}
E. Ringo's Favorite Numbers 3
对 \(1 \sim \sqrt{A}\) 中每个数判定它是否仅包含两个素因子
为了加速,可以从后往前验证
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
int main() {
const int M = 1e6;
vector<int> cnt(M+1);
for (int i = 2; i <= M; ++i) {
if (cnt[i]) continue;
for (int j = i; j <= M; j += i) cnt[j]++;
}
int q;
cin >> q;
rep(qi, q) {
ll a;
cin >> a;
ll x = sqrt(a);
while (cnt[x] != 2) x--;
cout << x*x << '\n';
}
return 0;
}
F. Happy Birthday! 3
区间dp
dp[l][r] 表示将区间 \([l, r]\) 染成目标颜色的最小代价
dp2[l][r] 表示将区间 \([l, r]\) 染成目标颜色或 \(c[l]\) 的最小代价
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
inline void chmin(ll& x, ll y) { if (x > y) x = y; }
int main() {
int n;
cin >> n;
vector<int> c(n), x(n);
rep(i, n) cin >> c[i], c[i]--;
rep(i, n) cin >> x[i];
const ll INF = 1e18;
vector dp(n, vector<ll>(n, INF));
vector dp2(n, vector<ll>(n, INF));
rep(i, n) dp2[i][i] = x[c[i]];
auto get = [&](int l, int r) {
l = (l+n)%n;
r = (r+n)%n;
return dp[l][r];
};
auto get2 = [&](int l, int r) {
l = (l+n)%n;
r = (r+n)%n;
return dp2[l][r];
};
for (int w = 1; w <= n; ++w) {
rep(l, n) {
int r = (l+w-1)%n;
if (w > 1 and c[l] == c[r]) chmin(dp2[l][r], get2(l, r-1));
rep(i, w-1) chmin(dp2[l][r], get2(l, l+i)+get(l+i+1, r));
chmin(dp[l][r], dp2[l][r]+w);
rep(i, w-1) {
chmin(dp[l][r], get(l, l+i)+get(l+i+1, r));
}
}
}
ll ans = INF;
rep(l, n) chmin(ans, get(l, l+n-1));
cout << ans << '\n';
return 0;
}
G. Patisserie ABC 3
将美观度、美味度、受欢迎度打个标记,分别记为 \(1, 2, 3\)。
假设蛋糕按 \(\max(X_i, Y_i, Z_i)\) 从大到小排序时,以下成立。
- 存在一个最优解,其中从蛋糕 \(1\) 到蛋糕 \(2K\) 中,未被取到的蛋糕数量不超过 \(2\) 个。
定义 dp[i][j][k] 为“在考虑到第 \(i\) 个蛋糕时,被取到的蛋糕数量为 \(\min(2K,i)−j\),且每个标记的使用次数的奇偶性由 \(k\) 表示的情况下,价格的最大值”
由于 \(j\) 只需在 \(0\) 到 \(2\) 之间进行搜索,因此通过状态数为 \(24N\) 的动态规划,可以解决这个问题。
浙公网安备 33010602011771号