[关闭]
@Dmaxiya 2018-08-17T10:17:46.000000Z 字数 9164 阅读 1026

Codeforces Round #499 (Div. 2)

Codeforces


Contests 链接:Codeforces Round #499 (Div. 2)
过题数:5
排名:145/7830

A. Stages

题意

给出 个小写字母,从中选出 个小写字母构成一个字符串,要求构成的字符串中 ,要使字符串所有字符的权值和最小,输出最小权值和,每个字符对应的权值大小为

输入

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

输出

输出构成的字符串的最小权值,如果无法构成满足条件的字符串,输出

样例

输入 输出 提示
5 3
xyabd
29 以下为所有合法的字符串以及对应的权值:
"adx"(权值为 );
"ady"(权值为 );
"bdx"(权值为 );
"bdy"(权值为 )。
"adx" 是权值最小的字符串,权值为
7 4
problem
34 最优的字符串 "belo" 的权值为
2 2
ab
-1 的值都为 ,所以只能将 都选上,但是 "ab" 并不是满足条件的字符串,因此应该输出
12 1
abaabbaaabbb
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 <sstream>
  17. using namespace std;
  18. #define LL long long
  19. const int maxn = 100;
  20. int n, k, cnt;
  21. char str[maxn], ans[maxn];
  22. int main() {
  23. #ifdef Dmaxiya
  24. freopen("test.txt", "r", stdin);
  25. #endif // Dmaxiya
  26. ios::sync_with_stdio(false);
  27. while(scanf("%d%d%s", &n, &k, str) != EOF) {
  28. cnt = 0;
  29. int len = strlen(str);
  30. sort(str, str + len);
  31. ans[++cnt] = str[0];
  32. for(int i = 1; str[i]; ++i) {
  33. if(str[i] - ans[cnt] > 1) {
  34. ans[++cnt] = str[i];
  35. }
  36. }
  37. if(cnt < k) {
  38. printf("-1\n");
  39. continue;
  40. }
  41. int sum = 0;
  42. for(int i = 1; i <= k; ++i) {
  43. sum += ans[i] - 'a' + 1;
  44. }
  45. printf("%d\n", sum);
  46. }
  47. return 0;
  48. }

B. Planning The Expedition

题意

个人和 袋食物,第 个袋子里装的食物种类是 ,每个人每天要吃一袋食物,且他们必须从头到尾都只吃同一种食物。问这些食物最多能够所有人吃多少天。

输入

第一行包含两个整数 ,第二行包含 个整数

输出

输出最多的天数。

样例

输入 输出 提示
4 10
1 5 2 1 1 1 2 5 7 2
2 可以将第 种食物分配给第 个人,第 种食物分配给第 个人,
种食物分配给第 个人。
100 1
1
0 总共有 个人而只有 袋食物,他们连一天都撑不过。
2 5
5 4 3 2 1
1
3 9
42 42 42 42 42 42 42 42 42
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 <sstream>
  17. using namespace std;
  18. #define LL long long
  19. const int maxn = 100 + 100;
  20. int n, m, ans, x;
  21. int num[maxn], tmp[maxn];
  22. bool judge(int x) {
  23. int Index = 1;
  24. memcpy(tmp, num, sizeof(num));
  25. for(int i = 1; i <= n; ++i) {
  26. while(Index <= 100 && tmp[Index] < x) {
  27. ++Index;
  28. }
  29. if(Index > 100) {
  30. return false;
  31. }
  32. tmp[Index] -= x;
  33. }
  34. return true;
  35. }
  36. int main() {
  37. #ifdef Dmaxiya
  38. freopen("test.txt", "r", stdin);
  39. #endif // Dmaxiya
  40. ios::sync_with_stdio(false);
  41. while(scanf("%d%d", &n, &m) != EOF) {
  42. memset(num, 0, sizeof(num));
  43. for(int i = 1; i <= m; ++i) {
  44. scanf("%d", &x);
  45. ++num[x];
  46. }
  47. for(int i = m; i >= 0; --i) {
  48. if(judge(i)) {
  49. ans = i;
  50. break;
  51. }
  52. }
  53. printf("%d\n", ans);
  54. }
  55. return 0;
  56. }

C. Fly

题意

一个火箭要从第 个星球经过 个星球后回到第 个星球,每到达一个星球都要经历降落与升空的过程,由于每个星球的引力不同,在每个星球降落与升空的过程中需要消耗的动力也不同。
火箭自身有一个质量 ,如果到达第 个星球时的油的质量为 吨,且在降落/升空过程中每吨重量需要消耗的油量为 吨,则在这个过程中需要消耗的总油量为 。在第 个星球升空时每吨重量需要消耗的油量为 吨,降落时每吨重量消耗的油量为 吨,问要完成整个任务所需要的最少油量为多少。

输入

前两行为两个整数 ,第三行为 个整数 ,第四行为 个整数 ,其中

输出

输出完成任务需要的最少油量,如果无法完成任务,则输出 ,误差在 以内都认为答案正确。

样例

输入 输出 提示
2
12
11 8
7 5
10.0000000000 火箭的初始质量为
离开第 个星球需要的油的质量为 吨,剩下 吨总质量;
在第 个星球降落时的总质量为 ,需要的油的质量为 吨,剩下 吨总质量;
离开第 个星球需要的油的质量为 吨,剩下 吨总质量;
在第 个星球降落需要的油的质量为 吨,剩下 吨总质量,油刚好用完。
3
1
1 4 1
2 5 3
-1 火箭永远都无法离开第 个星球。
6
2
4 6 3 3 5 6
2 6 3 6 5 3
85.4800000000

题解

中只要存在 ,就永远无法完成任务,否则可以二分初始油量,每次 判断油量是否会在中途消耗完,为减少精度误差,二分 次。

过题代码

  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 <sstream>
  17. using namespace std;
  18. #define LL long long
  19. const int maxn = 1000 + 100;
  20. bool flag;
  21. int n, m;
  22. int a[maxn], b[maxn];
  23. bool judge(double mid) {
  24. for(int i = 1; i <= n; ++i) {
  25. int ii = (i + 1) % n;
  26. if(ii == 0) {
  27. ii = n;
  28. }
  29. mid -= (m + mid) / a[i];
  30. if(mid < 0) {
  31. return false;
  32. }
  33. mid -= (m + mid) / b[ii];
  34. if(mid < 0) {
  35. return false;
  36. }
  37. }
  38. return true;
  39. }
  40. int main() {
  41. #ifdef Dmaxiya
  42. freopen("test.txt", "r", stdin);
  43. #endif // Dmaxiya
  44. ios::sync_with_stdio(false);
  45. while(scanf("%d%d", &n, &m) != EOF) {
  46. flag = true;
  47. for(int i = 1; i <= n; ++i) {
  48. scanf("%d", &a[i]);
  49. if(a[i] == 1) {
  50. flag = false;
  51. }
  52. }
  53. for(int i = 1; i <= n; ++i) {
  54. scanf("%d", &b[i]);
  55. if(b[i] == 1) {
  56. flag = false;
  57. }
  58. }
  59. if(!flag) {
  60. printf("-1\n");
  61. continue;
  62. }
  63. double low = 0;
  64. double high = 1e9;
  65. double mid;
  66. for(int i = 0; i < 500; ++i) {
  67. mid = (low + high) / 2;
  68. if(judge(mid)) {
  69. high = mid;
  70. } else {
  71. low = mid;
  72. }
  73. }
  74. printf("%.10f\n", high);
  75. }
  76. return 0;
  77. }

D. Rocket

题意

和机器人玩一个猜数字的游戏,要被猜中的数字为 ,最开始机器人会告诉 两个整数 ,表示 每次询问一个整数 ,如果 ,正确的回复应该是 ,如果 ,正确的回复应该是 ,如果 ,正确的回复应该是 ,机器人自己有一个长度为 序列, 不知道这个序列是什么样的,机器人在 的第 次询问中( 开始计数),如果序列中的第 个数字为 ,则机器人会回复正确的值 ,否则会回复 。要求 次询问内猜中

输入

第一次输入为两个整数 ,之后的输入根据题给规则给出。

输出

每次输出一个整数 ,要求在 次输出内得到 的值,且程序必须在得到 的回复时立即退出。

样例

输入 输出 提示
5 2

1

-1

-1

1

0

1

2

4

5

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 <sstream>
  17. using namespace std;
  18. #define LL long long
  19. const int maxn = 100 + 100;
  20. int n, m, x;
  21. int num[maxn];
  22. int main() {
  23. #ifdef Dmaxiya
  24. // freopen("test.txt", "r", stdin);
  25. #endif // Dmaxiya
  26. ios::sync_with_stdio(false);
  27. scanf("%d%d", &m, &n);
  28. printf("1\n");
  29. fflush(stdout);
  30. scanf("%d", &x);
  31. if(x == 0) {
  32. return 0;
  33. }
  34. num[0] = x;
  35. for(int i = 1; i < n; ++i) {
  36. printf("1\n");
  37. fflush(stdout);
  38. scanf("%d", &num[i]);
  39. }
  40. int low = 1;
  41. int high = m + 1;
  42. int mid;
  43. int Index = 0;
  44. while(high - low > 1) {
  45. mid = (low + high) / 2;
  46. printf("%d\n", mid);
  47. fflush(stdout);
  48. scanf("%d", &x);
  49. if(x == 0) {
  50. return 0;
  51. }
  52. if(num[Index] == -1) {
  53. x = -x;
  54. }
  55. if(x == 1) {
  56. low = mid;
  57. } else {
  58. high = mid;
  59. }
  60. Index = (Index + 1) % n;
  61. }
  62. return 0;
  63. }

E. Border

题意

给定 个整数 以及 的值,求 的所有取值,其中 为任意非负整数且

输入

第一行为两个整数 ,第二行为 个整数

输出

第一行输出一个整数 表示所有取值的数量,第二行按从小到大的顺序输出所有 的值。

样例

输入 输出 提示
2 8
12 20
2
0 4



即使有其他的系数 使 得到其他的值,但是所有其他值对 取模后的值都为
或者
3 10
10 20 30
1
0
三个数字都是 的倍数,因此无论如何组合它们的和都是 的倍数。

题解

对于任意一个数字 ,其 的值一定是 的倍数,两个数字 任意组合再对 取模的值一定是 ,以此类推,只要得到所有数字与 的最大公约数即可。

过题代码

  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 <sstream>
  17. using namespace std;
  18. #define LL long long
  19. const int maxn = 100000 + 100;
  20. int n, k;
  21. int num[maxn];
  22. int gcd(int a, int b) {
  23. return (b == 0? a: gcd(b, a % b));
  24. }
  25. int main() {
  26. #ifdef Dmaxiya
  27. freopen("test.txt", "r", stdin);
  28. #endif // Dmaxiya
  29. ios::sync_with_stdio(false);
  30. while(scanf("%d%d", &n, &k) != EOF) {
  31. int g = k;
  32. for(int i = 0; i < n; ++i) {
  33. scanf("%d", &num[i]);
  34. g = gcd(g, num[i]);
  35. }
  36. printf("%d\n", k / g);
  37. for(int i = 0; i < k; i += g) {
  38. if(i != 0) {
  39. printf(" ");
  40. }
  41. printf("%d", i);
  42. }
  43. printf("\n");
  44. }
  45. return 0;
  46. }

F. Mars rover

题意

给出一个由 个元器件组成的电路,每个元器件的功能只可能是“输入”、“与运算”、“或运算”、“非运算”、“异或运算”中的一个,整个电路是一个树形结构,只有一个输出,如果对某个输入取反,则可能会改变最终的输出,问对于每一个输入,如果仅将这个输入取反,得到的最终输出的结果。

输入

第一行包含一个整数 ,接下去 行,第 行的第一个字符串表示元器件类型:"IN"、"AND"、"OR"、"XOR"、"NOT",其中 "AND"、"OR"、"XOR" 后面跟两个数字,表示这个元器件的两个输入元器件编号,"NOT" 后面跟一个数字,表示这个元器件的一个输入元器件的编号,"IN" 后面跟着 或者 ,表示这个输入元器件的初始输入值。数据保证最终输出元器件编号为

输出

按元器件编号从小到大的顺序输出每一个输入元器件取反后输出的值,每一个输入元器件取反是相互独立的,即每个输出都是在仅改变一个输入元器件的值的情况下的输出。

样例

输入 输出 提示
10
AND 9 4
IN 1
IN 1
XOR 6 5
AND 3 7
IN 0
NOT 10
IN 1
IN 1
AND 2 8
10110 对应的元器件结构如下图:



其中绿色元器件表示这个元器件的计算结果为 ,黄色表示值为
如果改变输入 的值为 ,则输出为
如果改变输入 的值为 ,则输出的值为
如果改变输入 的值为 ,则输出的值为
如果改变输入 的值为 ,则输出的值为
如果改变输入 的值为 ,则输出的值为

题解

由于每修改一个输入元器件的值,都只会修改树上一条路径上的值,与其他路径无关,所以可以预处理第 个元器件的计算结果修改为 且其他元器件的计算结果不变时,最终输出的值,两次 就可以得到结果。

过题代码

  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 <sstream>
  17. using namespace std;
  18. #define LL unsigned long long
  19. const int maxn = 1000000 + 100;
  20. int n, l, r;
  21. char str[maxn][10];
  22. int num[maxn], Y[maxn][2];
  23. vector<int> G[maxn];
  24. void dfs1(int x) {
  25. int len = G[x].size();
  26. for(int i = 0; i < len; ++i) {
  27. dfs1(G[x][i]);
  28. }
  29. switch(str[x][0]) {
  30. case 'A': num[x] = num[G[x][0]] & num[G[x][1]]; break;
  31. case 'O': num[x] = num[G[x][0]] | num[G[x][1]]; break;
  32. case 'X': num[x] = num[G[x][0]] ^ num[G[x][1]]; break;
  33. case 'N': num[x] = 1 - num[G[x][0]]; break;
  34. default: break;
  35. }
  36. }
  37. void dfs2(int x) {
  38. int len = G[x].size();
  39. for(int i = 0; i < len; ++i) {
  40. int xx = 1 - num[G[x][i]];
  41. switch(str[x][0]) {
  42. case 'A': Y[G[x][i]][xx] = Y[x][xx & num[G[x][1 - i]]]; break;
  43. case 'O': Y[G[x][i]][xx] = Y[x][xx | num[G[x][1 - i]]]; break;
  44. case 'X': Y[G[x][i]][xx] = Y[x][xx ^ num[G[x][1 - i]]]; break;
  45. case 'N': Y[G[x][i]][xx] = Y[x][1 - xx]; break;
  46. default: break;
  47. }
  48. dfs2(G[x][i]);
  49. }
  50. }
  51. int main() {
  52. #ifdef Dmaxiya
  53. freopen("test.txt", "r", stdin);
  54. #endif // Dmaxiya
  55. ios::sync_with_stdio(false);
  56. while(scanf("%d", &n) != EOF) {
  57. for(int i = 1; i <= n; ++i) {
  58. num[i] = -1;
  59. G[i].clear();
  60. scanf("%s", str[i]);
  61. if(str[i][0] == 'I') {
  62. scanf("%d", &num[i]);
  63. } else if(str[i][0] == 'A' || str[i][0] == 'O' || str[i][0] == 'X') {
  64. scanf("%d%d", &l, &r);
  65. G[i].push_back(l);
  66. G[i].push_back(r);
  67. } else if(str[i][0] == 'N') {
  68. scanf("%d", &l);
  69. G[i].push_back(l);
  70. }
  71. }
  72. dfs1(1);
  73. for(int i = 1; i <= n; ++i) {
  74. Y[i][num[i]] = num[1];
  75. }
  76. Y[1][1 - num[1]] = 1 - num[1];
  77. dfs2(1);
  78. for(int i = 1; i <= n; ++i) {
  79. if(str[i][0] == 'I') {
  80. printf("%d", Y[i][1 - num[i]]);
  81. }
  82. }
  83. printf("\n");
  84. }
  85. return 0;
  86. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注