当前位置:   article > 正文

Codeforces Round 916 (Div. 3)

Codeforces Round 916 (Div. 3)

A. Problemsolving Log

签到题,对于给出的字符串,记录每个字母出现的次数,然后遍历一遍,如果对应的字母出现的次数大于它的位次,则说明该题被解出来了,最后输出解题数量即可

点击查看代码
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cmath>
  5. #include<vector>
  6. #include<map>
  7. #include<queue>
  8. #include<set>
  9. using namespace std;
  10. typedef long long ll;
  11. const int N = 2*1e5 + 10;
  12. void solve()
  13. {
  14. int n;
  15. cin >> n;
  16. string s;
  17. cin >> s;
  18. int st[27] = { 0 };
  19. int count = 0;
  20. for (int i = 0; i < s.size(); i++)
  21. {
  22. st[s[i] - 'A' + 1]++;
  23. }
  24. for (int i = 1; i < 27; i++)
  25. {
  26. if (st[i] >= i) count++;
  27. }
  28. cout << count << endl;
  29. }
  30. int main() {
  31. int t;
  32. cin >> t;
  33. while (t--)
  34. solve();
  35. return 0;
  36. }

B. Preparing for the Contest

排序问题,兴奋 k 次,即前 1k 按照升序排列,剩下的按照降序排序即可

点击查看代码
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cmath>
  5. #include<vector>
  6. #include<map>
  7. using namespace std;
  8. typedef long long ll;
  9. ll gcd(ll x, ll y) { //最大公约数
  10. while (y ^= x ^= y ^= x %= y);
  11. return x;
  12. }
  13. ll lcm(ll x, ll y) { //最小公倍数
  14. return x * y / gcd(x, y);
  15. }
  16. void solve() {
  17. int x, k;
  18. cin >> x >> k;
  19. int no = 0;
  20. for (int i = 1; i<=x; i++)
  21. {
  22. if (k != 0)
  23. cout << i << " ";
  24. else
  25. {
  26. no = i;
  27. break;
  28. }
  29. k--;
  30. }
  31. for (int i = x; i >= no; i--)
  32. {
  33. cout << i << " ";
  34. }
  35. cout << endl;
  36. }
  37. int main() {
  38. int t;
  39. cin >> t;
  40. while (t--)
  41. solve();
  42. return 0;
  43. }

C. Quests

暴力贪心,先用前缀和预处理数组 a ,之后对于数组 b ,用一个数组 d[i] 表示前 i 个中最大的 b ,最后遍历一遍, ans 取最大的 c[i]+(yi)×d[i]

点击查看代码
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cmath>
  5. #include<vector>
  6. #include<map>
  7. using namespace std;
  8. typedef long long ll;
  9. ll gcd(ll x, ll y) { //最大公约数
  10. while (y ^= x ^= y ^= x %= y);
  11. return x;
  12. }
  13. ll lcm(ll x, ll y) { //最小公倍数
  14. return x * y / gcd(x, y);
  15. }
  16. void solve() {
  17. ll x, y;
  18. cin >> x >> y;
  19. vector<ll>a(x+1);
  20. vector<ll>b(x+1);
  21. vector<ll>c(x + 1);
  22. vector<ll>d(x + 1);
  23. d[0] = 0;
  24. c[0] = 0;
  25. ll ans = 0;
  26. for (int i = 1; i <=x; i++)
  27. {
  28. cin >> a[i];
  29. c[i] = a[i] + c[i - 1];//前缀和
  30. // cout << c[i] <<" ";
  31. }
  32. for (int i = 1; i <=x; i++)
  33. {
  34. cin >> b[i];
  35. d[i] = max(d[i - 1], b[i]);//最大
  36. }
  37. for (int i = 1; i <=min(x,y); i++)
  38. {
  39. ll sum = c[i] + (y - i) * d[i];
  40. //cout << sum << " ";
  41. ans = max(ans, sum);
  42. }
  43. cout << ans << endl;
  44. }
  45. int main() {
  46. int t;
  47. cin >> t;
  48. while (t--)
  49. solve();
  50. return 0;
  51. }

D. Three Activities

暴力打表,先将每一个活动都排序(找出最多人数的3天),然后这3天互相排列组合,去除天数相同的,剩下的找最大值即是答案

点击查看代码
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cmath>
  5. #include<vector>
  6. #include<map>
  7. using namespace std;
  8. typedef long long ll;
  9. const int N = 1e5 + 10;
  10. ll gcd(ll x, ll y) { //最大公约数
  11. while (y ^= x ^= y ^= x %= y);
  12. return x;
  13. }
  14. ll lcm(ll x, ll y) { //最小公倍数
  15. return x * y / gcd(x, y);
  16. }
  17. struct no {
  18. ll num;
  19. ll day;
  20. }a[N],b[N],c[N];
  21. bool cmp(no x, no y)
  22. {
  23. return x.num > y.num;
  24. }
  25. void solve() {
  26. ll x;
  27. cin >> x;
  28. for (int i = 0; i < x; i++)
  29. {
  30. cin >> a[i].num;
  31. a[i].day = i;
  32. }
  33. for (int i = 0; i < x; i++)
  34. {
  35. cin >> b[i].num;
  36. b[i].day = i;
  37. }
  38. for (int i = 0; i < x; i++)
  39. {
  40. cin >> c[i].num;
  41. c[i].day = i;
  42. }
  43. sort(a, a + x, cmp);
  44. sort(b, b + x, cmp);
  45. sort(c, c + x, cmp);//由大到小排序
  46. ll ans = 0;
  47. for (int i = 0; i < 3; i++)
  48. {
  49. for (int j = 0; j < 3; j++)
  50. {
  51. for (int k = 0; k < 3; k++)
  52. {
  53. if (a[i].day != b[j].day && a[i].day != c[k].day && b[j].day != c[k].day)
  54. ans = max(a[i].num + b[j].num + c[k].num, ans);
  55. }
  56. }
  57. }
  58. cout << ans << endl;
  59. }
  60. int main() {
  61. int t;
  62. cin >> t;
  63. while (t--)
  64. solve();
  65. return 0;
  66. }

E. Game with Marbles

贪心排序问题,这一题 easyhard 差别不大, easy 应该暴力模拟可以过。计算每一组的权值, Alice (简称 A ), Bob (简称 B ) 对于 A 来说,选择的一组所获得的权值是 ai+bi1 (消除 bi 等于加 biB 拉开了 bi 的差距且保留了自己的剩余的 ai1 ,因此是 ai+bi1 );同理,对于 B 来说,也是这样,因此无论是 A 操作时还是 B 操作时,所选择的都是 ai+bi 最大值那一组 (每一组的权值都有 -1 因此可以仅比较 ai+bi) , 使用结构体存储每一组石子的数量和和组号,对石子数量进行排序,之后由大到小进行模拟即可。

点击查看代码
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cmath>
  5. #include<vector>
  6. #include<map>
  7. using namespace std;
  8. typedef long long ll;
  9. const int N = 1e5 + 10;
  10. ll gcd(ll x, ll y)
  11. { //最大公约数
  12. while (y ^= x ^= y ^= x %= y);
  13. return x;
  14. }
  15. ll lcm(ll x, ll y) { //最小公倍数
  16. return x * y / gcd(x, y);
  17. }
  18. struct non {
  19. ll num;
  20. ll step;
  21. }v[10];
  22. bool cmp(non x, non y) {
  23. return x.num < y.num;
  24. }
  25. void solve() {
  26. ll x;
  27. cin >> x;
  28. vector<ll>a(x + 1);
  29. vector<ll>b(x + 1);
  30. // vector<ll>v(x + 1);
  31. for (int i = 0; i < x; i++)
  32. {
  33. cin >> a[i];
  34. }
  35. for (int i = 0; i < x; i++)
  36. {
  37. cin >> b[i];
  38. }
  39. for (int i = 0; i < x; i++)
  40. {
  41. v[i].num = a[i] + b[i] - 1;
  42. v[i].step = i;
  43. }
  44. sort(v, v + x,cmp);
  45. //for (int i = 0; i < x; i++)
  46. //{
  47. // cout << v[i].num << " ";
  48. //}
  49. ll sum = 0;
  50. int j = 1;
  51. if (x % 2 == 0)
  52. {
  53. for (int i = x-1; i>=0; i--)
  54. {
  55. //cout << v[i] << " ";
  56. if (j == 1)
  57. {
  58. sum += a[v[i].step] - 1;
  59. }
  60. else
  61. sum -= b[v[i].step] - 1;
  62. j *= -1;
  63. }
  64. }
  65. else
  66. {
  67. for (int i = x - 1; i >= 0; i--)
  68. {
  69. if (i ==0)
  70. {
  71. sum += a[v[i].step] - 1;
  72. break;
  73. }
  74. else
  75. {
  76. if (j == 1)
  77. {
  78. sum += a[v[i].step] - 1;
  79. }
  80. else
  81. sum -= b[v[i].step] - 1;
  82. }
  83. j *= -1;
  84. }
  85. }
  86. cout << sum << endl;
  87. }
  88. int main() {
  89. int t;
  90. cin >> t;
  91. while (t--)
  92. solve();
  93. return 0;
  94. }

F. Programming Competition

这是一个树型结构 + dfs 的题目。一种贪心方法:

首先,叶子节点之间,不会存在上下级的关系,所以叶子节点都可以互相两两配对,所以我们只需要找叶子节点两两配对就行了。但是没这么简单,因为这并不是最优的。例如:

image

如果是这种情况,只考虑叶子节点配对,那么会出现 (4,3) 只能配对一次的情况,但是实际上可以 (4,5),(2,3) 配对;

所以需要这次贪心一下,每次配对的叶子节点都是深度最深的叶子节点,这样一来才有可能解放更多的深度较低的节点成为叶子节点,从而来使得它们与其他的叶子节点组成一组。

点击查看代码
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cmath>
  5. #include<vector>
  6. #include<map>
  7. #include<queue>
  8. using namespace std;
  9. typedef long long ll;
  10. const int N = 2 * 1e5 + 10;
  11. ll n, p[N], d[N], c[N];
  12. vector<ll>e[N];
  13. ll gcd(ll x, ll y) { //最大公约数
  14. while (y ^= x ^= y ^= x %= y);
  15. return x;
  16. }
  17. ll lcm(ll x, ll y) { //最小公倍数
  18. return x * y / gcd(x, y);
  19. }
  20. void dfs(ll u, ll v)//深度
  21. {
  22. d[u] = d[v] + 1;
  23. for (auto i = e[u].begin(); i != e[u].end(); i++)//遍历
  24. {
  25. //cout << *i << endl;
  26. dfs(*i, u);
  27. }
  28. }
  29. void solve() {
  30. cin >> n;
  31. d[0] = 0;
  32. for (int i = 2; i <=n; i++)
  33. {
  34. cin >> p[i];
  35. e[p[i]].push_back(i);
  36. c[p[i]]++;//子节点个数
  37. }
  38. dfs(1, 0);
  39. priority_queue<pair<ll, ll>>q;//优先队列,先将根深的进行组合
  40. for (int i = 2; i <= n; i++)
  41. {
  42. if (c[i] == 0)//叶子节点
  43. q.push(make_pair(d[i], i));
  44. }
  45. //while (!q.empty())
  46. //{
  47. // cout << q.top().second;
  48. // q.pop();
  49. //}
  50. ll ans = 0;
  51. while (q.size() >= 2)//单个
  52. {
  53. ll xx = q.top().second;//配队的第一个
  54. q.pop();
  55. ll yy = q.top().second;
  56. q.pop();
  57. ans++;//成功配队一对
  58. // cout << p[xx] << " " << p[yy] << endl;
  59. c[p[xx]]--;
  60. c[p[yy]]--;
  61. if (c[p[xx]] == 0)
  62. q.push(make_pair(d[p[xx]], p[xx]));
  63. if (c[p[yy]] == 0&&p[xx]!=p[yy])
  64. q.push(make_pair(d[p[yy]], p[yy]));
  65. }
  66. cout << ans << endl;//输出答案
  67. for (int i = 0; i <= n; i++)
  68. {
  69. c[i] = 0;
  70. p[i] = 0;
  71. d[i] = 0;
  72. e[i].clear();
  73. }
  74. }
  75. int main() {
  76. int t;
  77. cin >> t;
  78. while (t--)
  79. solve();
  80. return 0;
  81. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/1020619
推荐阅读
相关标签
  

闽ICP备14008679号