[关闭]
@Dmaxiya 2018-08-17T10:25:38.000000Z 字数 7661 阅读 952

Codeforces Round #490 (Div. 3)

Codeforces


Contests 链接:Codeforces Round #490 (Div. 3)
过题数:5
排名:125/7615

A. Mishka and Contest

题意

给出 个问题的难度等级序列, 只能解决难度等级不大于 的问题,她每次解决问题都是从序列的前面或者后面选一个问题,如果她可以解决这个问题,那么这个问题就会从序列中删掉,她将会重复这个操作,直到她无法解决任何问题为止,问题她最多能解决多少问题。

输入

第一行为两个整数 ,第二行有 个整数 ,表示问题的难度。

输出

输出 能解决的最多的问题数。

样例

输入 输出 提示
8 4
4 2 3 1 5 1 6 4
5 可以按照 [4,2,3,1,5,1,6,4][2,3,1,5,1,6,4]
[2,3,1,5,1,6][3,1,5,1,6][1,5,1,6][5,1,6] 的顺序最多解决 个问题。
5 2
3 1 2 1 3
0 由于序列两端的问题难度都大于 ,所以 无法解决任何问题。
5 100
12 34 55 43 21
5 可以解决所有问题。

题解

先判断序列中是否有大于 的项,如果没有则直接输出 ,否则从两端找到最多的不大于 的数字个数相加。

过题代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cmath>
  5. #include <climits>
  6. #include <cstring>
  7. #include <string>
  8. #include <vector>
  9. #include <list>
  10. #include <queue>
  11. #include <stack>
  12. #include <map>
  13. #include <set>
  14. #include <bitset>
  15. #include <algorithm>
  16. #include <functional>
  17. #include <iomanip>
  18. using namespace std;
  19. typedef long long LL;
  20. const int maxn = 200;
  21. int n, k;
  22. int num[maxn];
  23. int main() {
  24. #ifdef Dmaxiya
  25. freopen("test.txt", "r", stdin);
  26. // freopen("test1.out", "w", stdout);
  27. #endif // Dmaxiya
  28. ios::sync_with_stdio(false);
  29. while(scanf("%d%d", &n, &k) != EOF) {
  30. bool flag = true;
  31. for(int i = 1; i <= n; ++i) {
  32. scanf("%d", &num[i]);
  33. if(num[i] > k) {
  34. flag = false;
  35. }
  36. }
  37. if(flag) {
  38. printf("%d\n", n);
  39. continue;
  40. }
  41. int cnt = 0;
  42. for(int i = 1; i <= n; ++i) {
  43. if(num[i] > k) {
  44. break;
  45. }
  46. ++cnt;
  47. }
  48. for(int i = n; i >= 1; --i) {
  49. if(num[i] > k) {
  50. break;
  51. }
  52. ++cnt;
  53. }
  54. printf("%d\n", cnt);
  55. }
  56. return 0;
  57. }

B. Reversing Encryption

题意

对一个长度为 的字符串,从 枚举 的所有因数 ,将字符串在区间 上的所有字符反转,将得到一个新的字符串,如:"codeforces""secrofedoc""orcesfedoc""rocesfedoc""rocesfedoc"。
现在给出进行以上操作之后的字符串,输出原字符串。

输入

第一行为一个整数 ,第二行为一个长度为 的字符串 仅包含小写字符。

输出

输出原字符串。

样例

输入 输出
10
rocesfedoc
codeforces
16
plmaetwoxesisiht
thisisexampletwo
1
z
z

题解

枚举所有 的因数 ,将区间 内的所有字符反转,就能得到原字符串。

过题代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cmath>
  5. #include <climits>
  6. #include <cstring>
  7. #include <string>
  8. #include <vector>
  9. #include <list>
  10. #include <queue>
  11. #include <stack>
  12. #include <map>
  13. #include <set>
  14. #include <bitset>
  15. #include <algorithm>
  16. #include <functional>
  17. #include <iomanip>
  18. using namespace std;
  19. typedef long long LL;
  20. const int maxn = 100 + 100;
  21. int n;
  22. char str[maxn];
  23. void Reverse(int Index) {
  24. for(int i = 1; i <= Index / 2; ++i) {
  25. swap(str[i], str[Index - i + 1]);
  26. }
  27. }
  28. int main() {
  29. #ifdef Dmaxiya
  30. freopen("test.txt", "r", stdin);
  31. // freopen("test1.out", "w", stdout);
  32. #endif // Dmaxiya
  33. ios::sync_with_stdio(false);
  34. while(scanf("%d", &n) != EOF) {
  35. scanf("%s", str + 1);
  36. for(int i = 1; i <= n; ++i) {
  37. if(n % i == 0) {
  38. Reverse(i);
  39. }
  40. }
  41. printf("%s\n", str + 1);
  42. }
  43. return 0;
  44. }

C. Alphabetic Removals

题意

给出一个长度为 的只包含小写字符的字符串 ,输出对 进行 次以下操作后的字符串:

  • 如果字符串内含有字符 'a',则删掉最左边的那个 'a',否则进入下一步;
  • 如果字符串内含有字符 'b',则删掉最左边的那个 'b',否则进入下一步;
  • 如果字符串内有 'z',则删掉最左边的 'z'。

输入

第一行为两个整数 ,第二行为一个字符串

输出

输出经过 次删除字符的操作的字符串。

样例

输入 输出
15 3
cccaabababaccbc
cccbbabaccbc
15 9
cccaabababaccbc
cccccc
1 1
u

题解

先统计每个字符出现的次数,然后根据 计算出每个字符要删除多少次,然后 跑一遍整个字符串,每跑到一个字符就判断这个字符是否需要删除,如果需要删除就将该字符需要删除的次数减一,否则输出这个字符。

过题代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cmath>
  5. #include <climits>
  6. #include <cstring>
  7. #include <string>
  8. #include <vector>
  9. #include <list>
  10. #include <queue>
  11. #include <stack>
  12. #include <map>
  13. #include <set>
  14. #include <bitset>
  15. #include <algorithm>
  16. #include <functional>
  17. #include <iomanip>
  18. using namespace std;
  19. typedef long long LL;
  20. const int maxn = 400000 + 100;
  21. int n, k;
  22. char str[maxn];
  23. int cnt[30], Del[30];
  24. int main() {
  25. #ifdef Dmaxiya
  26. freopen("test.txt", "r", stdin);
  27. // freopen("test1.out", "w", stdout);
  28. #endif // Dmaxiya
  29. ios::sync_with_stdio(false);
  30. while(scanf("%d%d", &n, &k) != EOF) {
  31. memset(cnt, 0, sizeof(cnt));
  32. memset(Del, 0, sizeof(Del));
  33. scanf("%s", str);
  34. for(int i = 0; i < n; ++i) {
  35. ++cnt[str[i] - 'a'];
  36. }
  37. int Index = 0;
  38. while(k > 0) {
  39. if(k > cnt[Index]) {
  40. Del[Index] = cnt[Index];
  41. k -= cnt[Index];
  42. ++Index;
  43. } else {
  44. Del[Index] = k;
  45. break;
  46. }
  47. }
  48. for(int i = 0; i < n; ++i) {
  49. if(Del[str[i] - 'a'] <= 0) {
  50. putchar(str[i]);
  51. }
  52. --Del[str[i] - 'a'];
  53. }
  54. printf("\n");
  55. }
  56. return 0;
  57. }

D. Equalize the Remainders

题意

给定两个整数 ,保证 为整数,以及 个整数的序列 表示序列中对 取模等于 的数字个数。
现在你可以对这个序列进行修改,每次修改可以将序列中的某个数字 ,问最少需要多少次修改,能够使得 ,并输出修改后的序列。

输入

第一行为两个整数 ,数据保证 ,第二行为 个整数

输出

第一行输出要使 的最少修改次数,第二行为 个整数,表示修改后的序列,如果有多解,输出任意一组,输出要保证每个数字都不应超过

样例

输入 输出
6 3
3 2 0 6 10 12
3
3 2 0 7 10 14
4 2
0 1 2 3
0
0 1 2 3

题解

这题整体的思路就是贪心,如果 大于 个,将其中多出来的数字转化成离他“最近”的 小于 的数字。
思路很好想,就是代码的实现上如果没想清楚的话可能会写得很复杂,我的写法是这样的:用一个 数组来存,第 存的是所有的对 取模等于 的数字的下标,然后一直调整 中的数字个数,直到所有 的大小都等于 为止,调整的方法是:用一个 来跑 数组的那个 ,同时用一个队列,如果第 大于 ,就把第 后面的元素放入队列,如果第 小于 ,就把队首元素弹出,放到这个 后面,并将这个元素弹出队列, 的跑法是

过题代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cmath>
  5. #include <climits>
  6. #include <cstring>
  7. #include <string>
  8. #include <vector>
  9. #include <list>
  10. #include <queue>
  11. #include <stack>
  12. #include <map>
  13. #include <set>
  14. #include <bitset>
  15. #include <algorithm>
  16. #include <functional>
  17. #include <iomanip>
  18. using namespace std;
  19. typedef long long LL;
  20. const int maxn = 200000 + 100;
  21. int n, m;
  22. int num[maxn];
  23. vector<int> G[maxn];
  24. queue<int> que;
  25. bool vis[maxn];
  26. int main() {
  27. #ifdef Dmaxiya
  28. freopen("test.txt", "r", stdin);
  29. // freopen("test1.out", "w", stdout);
  30. #endif // Dmaxiya
  31. ios::sync_with_stdio(false);
  32. while(scanf("%d%d", &n, &m) != EOF) {
  33. for(int i = 0; i < m; ++i) {
  34. G[i].clear();
  35. vis[i] = false;
  36. }
  37. int k = n / m;
  38. for(int i = 1; i <= n; ++i) {
  39. scanf("%d", &num[i]);
  40. G[num[i] % m].push_back(i);
  41. }
  42. int cnt = 0;
  43. int Index = 0;
  44. while(cnt < m) {
  45. while((int)G[Index].size() > k) {
  46. que.push(G[Index].back());
  47. G[Index].pop_back();
  48. }
  49. while((int)G[Index].size() < k && !que.empty()) {
  50. int tmp = que.front();
  51. que.pop();
  52. G[Index].push_back(tmp);
  53. }
  54. if((int)G[Index].size() == k && !vis[Index]) {
  55. vis[Index] = true;
  56. ++cnt;
  57. }
  58. Index = (Index + 1) % m;
  59. }
  60. LL ans = 0;
  61. for(int i = 0; i < m; ++i) {
  62. int len = G[i].size();
  63. for(int j = 0; j < len; ++j) {
  64. int Index = G[i][j];
  65. int d = ((i - (num[Index] % m)) % m + m) % m;
  66. ans += d;
  67. num[Index] += d;
  68. }
  69. }
  70. printf("%I64d\n", ans);
  71. for(int i = 1; i <= n; ++i) {
  72. if(i != 1) {
  73. printf(" ");
  74. }
  75. printf("%d", num[i]);
  76. }
  77. printf("\n");
  78. }
  79. return 0;
  80. }

E. Reachability from the Capital

题意

在一个 个节点、 条边的有向图上,问最少要添加多少条有向边,使节点 能到达所有节点。

输入

第一行包含三个整数 ,接下来 行每行两个数字 ,表示在有向图上有一条从节点 指向 的边。

输出

输出要让节点 能够到达其他点需要添加的最少的有向边的数量。

样例

输入 输出 提示
9 9 1
1 2
1 3
2 3
1 5
5 6
6 1
1 8
9 8
7 1
3 有向图如图所示:

可以添加这三条有向边:,让节点 能到达其他所有节点,
是最少需要添加的有向边的数量。
5 4 5
1 2
2 3
3 4
4 1
1 有向图如图所示:

你可以添加 中的任意一条有向边,使 能到达
其他所有节点。

题解

先对整张图做 缩点,统计新图上入度为 的节点数量。

过题代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cmath>
  5. #include <climits>
  6. #include <cstring>
  7. #include <string>
  8. #include <vector>
  9. #include <list>
  10. #include <queue>
  11. #include <stack>
  12. #include <map>
  13. #include <set>
  14. #include <bitset>
  15. #include <algorithm>
  16. #include <functional>
  17. #include <iomanip>
  18. using namespace std;
  19. typedef long long LL;
  20. const int maxn = 5000 + 100;
  21. int n, m, u, v, s, ans;
  22. int top, bcnt, dcnt;
  23. int sta[maxn], dfn[maxn], low[maxn], belong[maxn], deg[maxn];
  24. bool ins[maxn];
  25. vector<int> G[maxn];
  26. void dfs(int x) {
  27. dfn[x] = low[x] = ++dcnt;
  28. ins[x] = true;
  29. sta[top++] = x;
  30. int len = G[x].size();
  31. for(int i = 0; i < len; ++i) {
  32. int pos = G[x][i];
  33. if(dfn[pos] == 0) {
  34. dfs(pos);
  35. low[x] = min(low[x], low[pos]);
  36. } else if(ins[pos]) {
  37. low[x] = min(low[x], dfn[pos]);
  38. }
  39. }
  40. if(dfn[x] == low[x]) {
  41. ++bcnt;
  42. int pos;
  43. do {
  44. pos = sta[--top];
  45. ins[pos] = false;
  46. belong[pos] = bcnt;
  47. } while(pos != x);
  48. }
  49. }
  50. void Tarjan() {
  51. bcnt = top = dcnt = 0;
  52. memset(dfn, 0, sizeof(dfn));
  53. memset(ins, 0, sizeof(ins));
  54. for(int i = 1; i <= n; ++i) {
  55. if(dfn[i] == 0) {
  56. dfs(i);
  57. }
  58. }
  59. for(int i = 1; i <= bcnt; ++i) {
  60. deg[i] = 0;
  61. }
  62. for(int i = 1; i <= n; ++i) {
  63. int len = G[i].size();
  64. for(int j = 0; j < len; ++j) {
  65. int pos = G[i][j];
  66. int u = belong[i];
  67. int v = belong[pos];
  68. if(u != v) {
  69. ++deg[v];
  70. }
  71. }
  72. }
  73. }
  74. int main() {
  75. #ifdef Dmaxiya
  76. freopen("test.txt", "r", stdin);
  77. // freopen("test1.out", "w", stdout);
  78. #endif // Dmaxiya
  79. ios::sync_with_stdio(false);
  80. while(scanf("%d%d%d", &n, &m, &s) != EOF) {
  81. for(int i = 1; i <= n; ++i) {
  82. G[i].clear();
  83. }
  84. for(int i = 0; i < m; ++i) {
  85. scanf("%d%d", &u, &v);
  86. G[u].push_back(v);
  87. }
  88. Tarjan();
  89. ans = 0;
  90. for(int i = 1; i <= bcnt; ++i) {
  91. if(belong[s] != i && deg[i] == 0) {
  92. ++ans;
  93. }
  94. }
  95. printf("%d\n", ans);
  96. }
  97. return 0;
  98. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注