A. Gift Carpet
题意 从左到右选择四列,使得四列分别对应字母 v , i , k , a v,i,k,a v,i,k,a
string solve() {int n, m; cin >> n >> m;char s[N][N];char a[5] = "vika";int cnt = 0;for (int i = 0; i < n; i ++) cin >> s[i];for (int j = 0; j < m; j ++)for (int i = 0; i < n; i ++)if (s[i][j] == a[cnt]) {cnt ++;break;}if (cnt == 4) return yes;return no;
}
B. Sequence Game
题意 从 a a a 序列经过转换变成 b b b 序列,已知 b b b 序列,求任意一个可能的 a a a 序列
首先 b 0 ← a 0 b_0 ← a_0 b0←a0,然后只要满足 a i − 1 ≤ a i a_{i-1}\le a_i ai−1≤ai 就将 a i p u s h _ b a c k a_i~push\_back ai push_back 到 b b b 序列后面
void solve() {int n; cin >> n;vector<int> a(1);cin >> a[0];for (int i = 1; i < n; i ++) {int x; cin >> x;if (*(a.end() - 1) > x) a.push_back(x);a.push_back(x);}cout << a.size() << endl;for (auto i : a) cout << i << ' ';cout << endl;
}
C. Flower City Fence
题意 给出每个栅栏的高度(宽度为 1 1 1),问这个栅栏是否关于 y = x y=x y=x 对称
string solve() {int n; cin >> n;vector<int> a(n);for (auto &i : a) cin >> i;a.push_back(0);int idx = 0;for (int i = n - 1; i >= 0; i --) {int t = a[i] - a[i + 1];while (t --) if (a[idx ++] != i + 1) return no;}return yes;
}
D. Ice Cream Balls
题意 每两种球可以合成一种冰淇淋,且 ( i , j ) = ( j , i ) (i,j)=(j,i) (i,j)=(j,i)。特殊的,两个球 1 1 1 可以合成 ( 1 , 1 ) (1,1) (1,1)。问至少需要多少球能刚好合成 n n n 个冰淇淋
ll solve() {ll n; cin >> n;ll l = 0, r = 2e9;while (l < r) {ll mid = l + r + 1 >> 1;if (mid * (mid - 1) / 2 <= n) l = mid;else r = mid - 1;}ll res = l + (n - l * (l - 1) / 2);return res;
}
E. Kolya and Movie Theatre
题意 一共 n n n 天每天一场电影,最多看 m m m 场电影,每场电影的热度为 a i a_i ai,每次看电影的兴奋值为 a i − c n t ⋅ d a_i-cnt·d ai−cnt⋅d,其中 d d d 为给定常数, c n t cnt cnt 为距上次看电影的天数,求最终的兴奋值之和
题解 优先队列
ll solve() {int n, m, d; cin >> n >> m >> d;priority_queue<int, vector<int>, greater<int>> q;ll res = 0, sum = 0;for (int i = 1; i <= n; i ++) {int x; cin >> x;if (x <= 0) continue;if (q.size() < m) {sum += x;q.push(x);} else {sum += x;q.push(x);sum -= q.top();q.pop();}res = max(res, sum - (ll)i * d);}return res;
}
F. Magic Will Save the World
题意 有 n n n 个怪兽血量为 a i a_i ai,魔法师初始有 0 0 0 点水魔法和 0 0 0 点火魔法,每秒分别恢复 w , f w,f w,f 点,对于每个怪兽只能
法一: b i t s e t bitset bitset
int solve() {int n, w, f; cin >> w >> f >> n;bitset<N> b;b[0] = true;int sum = 0;for (int i = 1; i <= n; i ++) {int x; cin >> x;sum += x;b |= b << x;}int res = sum;for (int i = 0; i <= sum; i ++) {if (!b[i]) continue;int x = (i + w - 1) / w;int y = (sum - i + f - 1) / f;res = min(res, max(x, y));}return res;
}
法二: d p dp dp 因为是从二维优化到一维,因此 j j j 逆序枚举
int solve() {int n, w, f; cin >> w >> f >> n;vector<int> a(n);int sum = 0;for (auto &i : a) cin >> i, sum += i;vector<int> dp(sum + 1);dp[0] = 1;for (auto i : a)for (int j = sum; j >= i; j --)dp[j] |= dp[j - i];int res = sum;for (int i = 0; i <= sum; i ++) {if (!dp[i]) continue;int x = (i + w - 1) / w;int y = (sum - i + f - 1) / f;res = min(res, max(x, y));}return res;
}