比赛链接:https://atcoder.jp/contests/abc167/tasks
AB水题,
C - Skill Up
题意:
- 初始时
个算法的能力均为
,
次中每次可以花费
元提升
个算法的能力(提升程度可能不等),问
个算法能力都提升到不低于
的最少花费。
思路:
一开始想写DP的,但发现数据范围不是很大 #card=math&code=%28n%5Cle%2015%29) ,那么直接枚举即可了
int n, m, x;int c[15], a[15][15];int M[15], Min = 1e9, cost;void chmin(int &a, int b) { return (void)(a > b ? a = b : a = a); }void chmax(int &a, int b) { return (void)(a < b ? a = b : a = a); }bool check() {for (int i = 0; i < m; ++i) if (M[i] < x) return 0;return 1;}void dfs(int i) {if (i == n) {if (check()) chmin(Min, cost);return ;}cost += c[i];for (int j = 0; j < m; ++j) M[j] += a[i][j];dfs(i + 1);cost -= c[i];for (int j = 0; j < m; ++j) M[j] -= a[i][j];dfs(i + 1);}int main() {cin.tie(nullptr)->sync_with_stdio(false);cin >> n >> m >> x;for (int i = 0; i < n; ++i) {cin >> c[i];for (int j = 0; j < m; ++j) cin >> a[i][j];}dfs(0);cout << (Min == 1e9 ? -1 : Min);}
D - Teleporter
题意:
个城镇每个城镇有一个传送点可以传送到其他城镇,问从第一个城镇出发传送
次后所在的城镇。
思路:
模拟一下样例就知道传送过程中肯定存在环,那么我们标记环路起点,加上传送次数对环路长度的模值即可,需要注意有可能先在一些城镇间传送后才进入环路。
const int N = 2e5 + 10;ll n, k;ll a[N], pre[N];int main() {cin.tie(nullptr)->sync_with_stdio(false);cin >> n >> k;for (int i = 1; i <= n; ++i) cin >> a[i];int now = 1;ll cnt = 0;while (k--) {now = a[now];if (pre[now])k %= cnt - pre[now];pre[now] = cnt++;}cout << now;}
E - Colorful Blocks
题意:
- 给
个方块染色,可以使用
个颜色,要求最多有
对相邻方块同色。
思路:
%5E%7Bn-1-i%7D#card=math&code=ans%20%3D%20%5Csum%5Climits%7Bi%20%3D%200%7D%5Ekm%2AC%7Bn-1%7D%5Ei%2A%28m%20-%201%29%5E%7Bn-1-i%7D)
解释一下,第 个方块可以染
种颜色,从余下
个方块中选取
个方块,这
个方块组成同色的
对方块,它们的颜色与左相邻的方块相同,其余的
个方块因为不与左相邻方块同色,每个可以染
个颜色。
代码书写上用逆序处理一下,同时独立出 模块防止写错细节
const int N = 2e5 + 10, mod = 998244353;ll fac[N];ll add(ll a, ll b) {return (a + b) % mod;}ll mul(ll a, ll b) {return a * b % mod;}ll qpow(ll a, ll b) {ll ans = 1;for (; b; b >>= 1, a = mul(a, a)) if (b & 1) ans = mul(ans, a);return ans;}ll inv(ll n) {return qpow(n, mod - 2);}ll C(ll n, ll m) {return mul(fac[n], mul(inv(fac[m]), inv(fac[n - m])));}int main() {cin.tie(nullptr)->sync_with_stdio(false);fac[0] = 1;for (int i = 1; i < N; ++i) fac[i] = mul(fac[i - 1], i);ll n, m, k;cin >> n >> m >> k;ll ans = 0;for (int i = 0; i <= k; ++i)ans = add(ans, mul(m, mul(C(n - 1, i), qpow(m - 1, n - 1 - i))));cout << ans;}
F - Bracket Sequencing
题意:
- 能否将一些括号串编排为合法串。
思路:
这道题不会,参考了一下这个大佬的博客:Here
详细思路:GYM - 101341A
const int M = 1e6 + 100;int l[M], r[M];int id[M], tp[M];int main() {int n; cin >> n;for (int i = 0; i < n; i++) {string s; cin >> s;int x = 0, y = 0;for (char c : s) {if (c == '(') ++x;else if (x) --x;else ++y;}l[i] = x, r[i] = y, id[i] = i;if (y == 0) tp[i] = 1;else if (x == 0) tp[i] = 4;else if (x >= y) tp[i] = 2;else tp[i] = 3;}sort(id, id + n, [&] (int a, int b) {if (tp[a] != tp[b]) return tp[a] < tp[b];if (tp[a] == 2) {if (r[a] != r[b]) return r[a] < r[b];else return l[a] > l[b];}if (tp[a] == 3) return l[a] > l[b];return false;});int sum = 0;for (int i = 0; i < n; i++) {sum -= r[id[i]];if (sum < 0) break;sum += l[id[i]];}cout << (sum == 0 ? "Yes" : "No");}
