CodeCraft-21 and Codeforces Round #711 (Div. 2) A~C 个人题解
补题链接:Here
1498A. GCD Sum
题意:给定一个 gcdSum
操作:\(gcdSum(762) = gcd(762,7 + 6 + 2) = gcd(762,15) = 3\)
请问要执行多少次 gcdSum
才能使结果不为 \(1\)
输出最后的 \(n\) 值
思路:按题意来,因为数据范围在 1e18
在执行 gcdSum
时比较快
using ll = long long;
ll gcd(ll x, ll y) { return y == 0 ? x : gcd(y, x % y); }
ll getSum(ll n) {
ll s = 0;
while (n) {
s += n % 10, n /= 10;
}
return s;
}
int main() {
ios_base::sync_with_stdio(false), cin.tie(0);
int _;
for (cin >> _; _--;) {
ll n;
cin >> n;
while (gcd(n, getSum(n)) == 1) n++;
cout << n << "\n";
}
return 0;
}
1498B. Box Fitting
题意:在一个被限定了宽度的盒子中给一些长度为 \(2^x\) 高度为 \(1\) 的长方块,请问怎么排放才能使最终高度最小
思路:先利用 map
存储各个长度的值,然后二分找到在该行中最大的一块然后填充。
这里建议看代码理解
int main() {
ios_base::sync_with_stdio(false), cin.tie(0);
int _;
for (cin >> _; _--;) {
int n, w;
cin >> n >> w;
map<int, int> mp;
for (int i = 0, x; i < n; ++i) {
cin >> x;
mp[x]++;
}
int ans = 1, cur = w;
while (mp.size()) {
if (mp.begin()->first > cur) {
++ans, cur = w;
}
auto it = prev(mp.upper_bound(cur));
assert(it->first <= cur);
cur -= it->first;
if (--(it->second) == 0) mp.erase(it);
}
cout << ans << "\n";
}
return 0;
}
1498C. Planar Reflections
DP优化 + 模拟
题意:给定一个可以穿越墙体的微观粒子(寿命为 \(k\)),但是每穿越一次墙体会产生一个反向寿命为 \(k - 1\) 的粒子。
请问最终共有多少个粒子?
思路:模拟变化过程,然后开DP数组存储已经计算过的即可,写的时候要注意细节,比如什么时候 \(k - 1\) 或者 \(1 - dir\) 方向变化
const int mod = 1e9 + 7;
int n, k;
int dp[1010][1010][2];
int solve(int cur, int k, int dir) {
if (k == 1) return 1;
// 非 -1 说明已经计算过了
if (dp[cur][k][dir] != -1) return dp[cur][k][dir];
int ans = 2; // 本身和穿过墙的复制体
if (dir == 1) {
if (cur < n) ans += solve(cur + 1, k, dir) - 1;
ans %= mod;
if (cur > 1) ans += solve(cur - 1, k - 1, 1 - dir) - 1;
ans %= mod;
dp[cur][k][dir] = ans;
} else {
if (cur > 1) ans += solve(cur - 1, k, dir) - 1;
ans %= mod;
if (cur < n) ans += solve(cur + 1, k - 1, 1 - dir) - 1;
ans %= mod;
dp[cur][k][dir] = ans;
}
return ans;
}
int main() {
ios_base::sync_with_stdio(false), cin.tie(0);
int _;
for (cin >> _; _--;) {
cin >> n >> k;
memset(dp, -1, sizeof dp);
cout << solve(1, k, 1) << '\n';
}
return 0;
}
在学习高榜大佬的代码时候发现的一种解法,Orz...
#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
int X[1001], Y[1001], n, k, K, R, val;
signed main() {
for (cin >> n; cin >> n >> k;) {
for (R = 0; R <= n; R++) X[R] = Y[R] = 0;
for (K = 2; K <= k; K++) {
for (R = n; R >= 0; R--) X[R] = (R + Y[n - R]) % mod;
val = 0;
for (R = n - 1; R >= 0; R--) Y[R] = (val += X[R]) %= mod;
}
cout << (1 + X[n]) % mod << ' ';
}
}