[关闭]
@Dmaxiya 2018-08-17T10:21:09.000000Z 字数 4766 阅读 1032

Codeforces Round #446 (Div. 2)

Codeforces


Contests 链接:Codeforces Round #446 (Div. 2)
过题数:3
排名:798/10599

A. Greed

题意

个可乐罐,第 个可乐罐的容量为 ,其中剩余的可乐体积为 ,问能否将所有可乐罐中剩余的可乐都倒到两个可乐罐中。

输入

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

输出

如果可以则输出 ,否则输出

样例

输入 输出 提示
2
3 5
3 6
YES 由于本来就已经有两个罐子,所以一定可以将所有可乐都倒到两个罐子中。
3
6 8 9
6 10 12
NO
5
0 0 5 0 0
1 1 8 10 5
YES
4
4 1 0 3
5 2 2 3
YES

题解

判断所有剩余可乐的体积 能否放入体积最大的两个罐子中即可。

过题代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cmath>
  5. #include <climits>
  6. #include <cfloat>
  7. #include <cstring>
  8. #include <string>
  9. #include <vector>
  10. #include <list>
  11. #include <queue>
  12. #include <stack>
  13. #include <map>
  14. #include <set>
  15. #include <algorithm>
  16. using namespace std;
  17. #define LL long long
  18. const int maxn = 100000 + 100;
  19. int n;
  20. LL a, sum;
  21. LL num[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", &n) != EOF) {
  28. sum = 0;
  29. for(int i = 0; i < n; ++i) {
  30. scanf("%I64d", &a);
  31. sum += a;
  32. }
  33. for(int i = 0; i < n; ++i) {
  34. scanf("%I64d", &num[i]);
  35. }
  36. sort(num, num + n);
  37. if(sum > num[n - 1] + num[n - 2]) {
  38. printf("NO\n");
  39. } else {
  40. printf("YES\n");
  41. }
  42. }
  43. return 0;
  44. }

B. Wrath

题意

个人站成一排,第 个人手里有一个长度为 的钩子,如果第 个人满足条件 ,那么这个人就会被杀死,铃声一响,所有人同时抛出钩子杀死前面的人,问最终有多少人存活。

输入

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

输出

在铃声响后,最终有多少人存活。

样例

输入 输出 提示
4
0 1 0 10
1 最后一个人杀死了在他前面的所有人。
2
0 0
2
10
1 1 3 0 0 0 2 1 0 3
3

题解

从后往前扫描,每扫描一个人将这个人能够杀死的人的最小位置记为 ,则如果这个人的位置 ,这个人就可以存活,不论这个人是否存活,都需要将 更新为

过题代码

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

C. Pride

题意

对于一个长度为 的序列,可以选择其中两个相邻的数字 ,并将它们中的其中一个用 进行替换,问至少要经过多少次操作,才能使得序列中所有数字都为

输入

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

输出

输出最少的操作次数,如果永远都无法达到目标,则输出

样例

输入 输出 提示
5
2 2 3 4 6
5 可以将序列经过以下变换达到目标:
4
2 4 6 8
-1
3
2 6 9
4

题解

首先取一个最短的区间,这个区间的最大公约数为 ,通过这个长度为 的区间得到一个 需要的操作次数为 ,然后再利用这个 与其他数字进行最大公约数的替换操作,操作次数等于除这个数字外,其他所有不等于 的数字的个数,可以由此得到答案。如果整个序列的最大公约数不为 ,则输出

过题代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cmath>
  5. #include <climits>
  6. #include <cfloat>
  7. #include <cstring>
  8. #include <string>
  9. #include <vector>
  10. #include <list>
  11. #include <queue>
  12. #include <stack>
  13. #include <map>
  14. #include <set>
  15. #include <algorithm>
  16. using namespace std;
  17. #define LL long long
  18. const int maxn = 2000 + 100;
  19. int n, Index, ans;
  20. int num[maxn];
  21. int gcd(int a, int b) {
  22. return (b == 0? a: gcd(b, a % b));
  23. }
  24. int main() {
  25. #ifdef Dmaxiya
  26. freopen("test.txt", "r", stdin);
  27. #endif // Dmaxiya
  28. ios::sync_with_stdio(false);
  29. while(scanf("%d", &n) != EOF) {
  30. ans = n + 1;
  31. Index = n + 1;
  32. for(int i = 1; i <= n; ++i) {
  33. scanf("%d", &num[i]);
  34. }
  35. for(int i = 1; i <= n; ++i) {
  36. int Gcd = num[i];
  37. if(Gcd == 1) {
  38. Index = i;
  39. ans = 0;
  40. break;
  41. }
  42. for(int j = i + 1; j <= n; ++j) {
  43. Gcd = gcd(Gcd, num[j]);
  44. if(Gcd == 1) {
  45. if(ans > j - i) {
  46. ans = j - i;
  47. Index = j;
  48. }
  49. break;
  50. }
  51. }
  52. }
  53. if(ans == n + 1) {
  54. printf("-1\n");
  55. continue;
  56. }
  57. for(int i = 1; i <= n; ++i) {
  58. if(num[i] != 1 && i != Index) {
  59. ++ans;
  60. }
  61. }
  62. printf("%d\n", ans);
  63. }
  64. return 0;
  65. }

D. Gluttony

题意

给定 个互不相等的数字 ,将 个数字重新生成一个排列 后,要求对于下标的任意一个非空真子集 ,都满足条件

输入

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

输出

如果可以构造出满足条件的序列 ,则按顺序输出 序列中的每一个元素,否则输出 ,有多解则输出任意一个。

样例

输入 输出
2
1 2
2 1
4
1000 100 10 1
100 1 1000 10

题解

首先考虑一个更简单的问题,对于一个有序的序列 ,如果我们将序列中的每个位置上的数字都往右移动一位,第 个数字移动到第 位,生成的新的序列为 ,首先考虑真子集不包含 的情况,则可以发现对于任意一个集合,原序列中的数字都大于新序列中的数字,而如果考虑 的情况,由于 对两个序列都是相等的,所以包含下标为 的情况的大小关系与不包含 的情况正好相反,原序列中的任意一个真子集数字的和都小于新序列中的数字和,因此不论如何总是可以满足题给条件。
对于乱序的序列 ,只要用一个结构体标记一下下标即可。

过题代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cmath>
  5. #include <climits>
  6. #include <cfloat>
  7. #include <cstring>
  8. #include <string>
  9. #include <vector>
  10. #include <list>
  11. #include <queue>
  12. #include <stack>
  13. #include <map>
  14. #include <set>
  15. #include <algorithm>
  16. using namespace std;
  17. #define LL long long
  18. const int maxn = 50;
  19. struct Node {
  20. int num, Index;
  21. };
  22. bool operator<(const Node &a, const Node &b) {
  23. return a.num < b.num;
  24. }
  25. int n;
  26. int num[maxn];
  27. Node node[maxn];
  28. int main() {
  29. #ifdef Dmaxiya
  30. freopen("test.txt", "r", stdin);
  31. #endif // Dmaxiya
  32. ios::sync_with_stdio(false);
  33. while(scanf("%d", &n) != EOF) {
  34. for(int i = 0; i < n; ++i) {
  35. scanf("%d", &num[i]);
  36. node[i].Index = i;
  37. node[i].num = num[i];
  38. }
  39. sort(node, node + n);
  40. for(int i = 1; i < n; ++i) {
  41. swap(node[i].Index, node[0].Index);
  42. }
  43. for(int i = 0; i < n; ++i) {
  44. num[node[i].Index] = node[i].num;
  45. }
  46. for(int i = 0; i < n; ++i) {
  47. if(i != 0) {
  48. printf(" ");
  49. }
  50. printf("%d", num[i]);
  51. }
  52. printf("\n");
  53. }
  54. return 0;
  55. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注