[关闭]
@Dmaxiya 2018-08-17T10:17:57.000000Z 字数 5976 阅读 993

Codeforces Round #464 (Div. 2)

Codeforces


Contests 链接:Codeforces Round #464 (Div. 2)
过题数:5
排名:236/10927

A. Love Triangle

题意

个没有性别区分的人编号为 ,每个人都有自己喜欢的人 ,问其中是否存在三角关系?如果 喜欢 喜欢 ,而 喜欢 ,则这三个人之间就存在三角关系。

输入

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

输出

如果存在三角关系,则输出 ,否则输出 ,大小写任意。

样例

输入 输出 提示
5
2 4 5 1 3
YES 之间存在三角关系。
5
5 5 5 5 1
NO

题解

对于每一个 判断 是否等于

过题代码

  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. using namespace std;
  17. #define LL long long
  18. const int maxn = 5000 + 100;
  19. int n;
  20. int f[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. bool flag = false;
  28. for(int i = 1; i <= n; ++i) {
  29. scanf("%d", &f[i]);
  30. }
  31. for(int i = 1; i <= n; ++i) {
  32. if(f[f[f[i]]] == i) {
  33. flag = true;
  34. break;
  35. }
  36. }
  37. if(flag) {
  38. printf("YES\n");
  39. } else {
  40. printf("NO\n");
  41. }
  42. }
  43. return 0;
  44. }

B. Hamster Farm

题意

只仓鼠,需要买一些箱子来将这些仓鼠装起来,总共有 种箱子,每种箱子能够装下 只仓鼠,只能选择其中一种箱子,且每个箱子都必须装满仓鼠,无法装满箱子的仓鼠就会被抛弃,要使被抛弃的仓鼠的数量最少,问应该用哪一种箱子,这种箱子需要多少个。

输入

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

输出

输出应该选择的箱子的编号(箱子按从 编号),以及需要这种箱子的数量。如果有多解输出任意一个。

样例

输入 输出
19 3
5 4 10
2 4
28 3
5 6 30
1 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. using namespace std;
  17. #define LL long long
  18. LL n, k, num, ans, Index;
  19. int main() {
  20. #ifdef Dmaxiya
  21. freopen("test.txt", "r", stdin);
  22. #endif // Dmaxiya
  23. ios::sync_with_stdio(false);
  24. while(scanf("%I64d%I64d", &n, &k) != EOF) {
  25. Index = 1;
  26. ans = (1LL << 63) - 1;
  27. for(int i = 1; i <= k; ++i) {
  28. scanf("%I64d", &num);
  29. if(n / num * num > n / ans * ans) {
  30. ans = num;
  31. Index = i;
  32. }
  33. }
  34. printf("%I64d %I64d\n", Index, n / ans);
  35. }
  36. return 0;
  37. }

C. Convenient For Everybody

题意

在地球上有 个时区,以第 个时区的时间为标准时,若第一个时区的时间为 ,那么第 个时区的时间就是 取模后的值,由于一天中没有 时的表示方法,只有 时的表示方法,所以第 个时区的时间就是 。现在要办一场 ,所有时区的人同时开始比赛,每一个时区的人都会在自己当地的时间区间 内开始参加比赛,如果比赛开始的时间超出了这个范围,他们就不会参加这个比赛,已知第 个时区有 个人参加比赛,问应该在第 个时区的什么时间举办比赛,才能让全世界参加比赛的人最多。

输入

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

输出

输出比赛开始的时间(标准时),如果有多个满足条件的答案,输出最小的一个。

样例

输入 输出 提示
3
1 2 3
1 3
3 如果在第 个时区的 时开始比赛,此时第 个时区的时间为 时,第 个时区的时间为 时,第 和第 个时区共 个人将会参加比赛。
5
1 2 3 4 1
1 3
4 如果在第 个时区的 时开始比赛,第 个时区的时间为 时,第 个时区的时间为 时,两个时区共 个人将会参加比赛。

题解

求一个长度为 的区间和最大值,然后将这个区间的第一个时区的本地开始时间转化为标准时,取标准时中的最小值。

过题代码

  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 = 200000 + 100;
  20. int n, s, t, ans, tmp, Max;
  21. int sum[maxn];
  22. int change(int x) {
  23. x = ((s - x) % n + n) % n;
  24. if(x == 0) {
  25. x = n;
  26. }
  27. return x;
  28. }
  29. int main() {
  30. #ifdef Dmaxiya
  31. freopen("test.txt", "r", stdin);
  32. #endif // Dmaxiya
  33. ios::sync_with_stdio(false);
  34. while(scanf("%d", &n) != EOF) {
  35. tmp = 0;
  36. ans = 1;
  37. Max = 0;
  38. for(int i = 1; i <= n; ++i) {
  39. scanf("%d", &sum[i]);
  40. sum[i + n] = sum[i];
  41. }
  42. scanf("%d%d", &s, &t);
  43. for(int i = 1; i <= 2 * n; ++i) {
  44. sum[i] += sum[i - 1];
  45. }
  46. int d = t - s;
  47. for(int i = 0; i < n; ++i) {
  48. if(sum[i + d] - sum[i] > Max) {
  49. tmp = i;
  50. Max = sum[i + d] - sum[i];
  51. ans = change(tmp);
  52. } else if(sum[i + d] - sum[i] == Max) {
  53. if(change(i) < ans) {
  54. tmp = i;
  55. ans = change(tmp);
  56. }
  57. }
  58. }
  59. printf("%d\n", ans);
  60. }
  61. return 0;
  62. }

D. Love Rescue

题意

给定两个长度为 的字符串 ,要将字符串 中的一些字符进行替换,使 ,如果有字符对 ,就可以将 中的 字符用 字符进行替换,反之亦然,问至少需要多少个字符对,可以将 变为

输入

第一行为一个整数 ,第二行和第三行分别为字符串 ,两个字符串都只包含小写字母。

输出

第一行为一个整数 ,表示最少需要的字符对数,接下去 行每行两个字符 ,表示字符 之间可以相互替换,如果有多解可以输出任意一组。

样例

输入 输出
3
abb
dad
2
a d
b a
8
drpepper
cocacola
7
l e
e d
d c
c p
p o
o r
r a

题解

将字符串 中所有相同位置上的字符做并查集,在同一个连通块内内字符只需要和根节点进行交换,就可以在连通块内任意地改变某个字符为另一个字符。

过题代码

  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, cnt;
  21. char str1[maxn], str2[maxn];
  22. int fa[30];
  23. vector<int> G[30];
  24. void Init() {
  25. for(int i = 0; i < 26; ++i) {
  26. fa[i] = i;
  27. G[i].clear();
  28. }
  29. }
  30. int Find(int x) {
  31. return (x == fa[x]? x: fa[x] = Find(fa[x]));
  32. }
  33. void unit(int x, int y) {
  34. int xx = Find(x);
  35. int yy = Find(y);
  36. fa[xx] = yy;
  37. }
  38. int main() {
  39. #ifdef Dmaxiya
  40. freopen("test.txt", "r", stdin);
  41. #endif // Dmaxiya
  42. ios::sync_with_stdio(false);
  43. while(scanf("%d%s%s", &n, str1, str2) != EOF) {
  44. cnt = 0;
  45. Init();
  46. for(int i = 0; i < n; ++i) {
  47. unit(str1[i] - 'a', str2[i] - 'a');
  48. }
  49. for(int i = 0; i < 26; ++i) {
  50. if(Find(i) != i) {
  51. G[Find(i)].push_back(i);
  52. ++cnt;
  53. }
  54. }
  55. printf("%d\n", cnt);
  56. for(int i = 0; i < 26; ++i) {
  57. int len = G[i].size();
  58. if(len == 0) {
  59. continue;
  60. }
  61. for(int j = 0; j < len; ++j) {
  62. printf("%c %c\n", 'a' + i, 'a' + G[i][j]);
  63. }
  64. }
  65. }
  66. return 0;
  67. }

E. Maximize!

题意

有一个集合 ,这个集合初始为空,有 次操作,每次操作可以是:

  1. 加入一个新的整数到集合中,这个整数一定大于当前集合中所有其他数字;
  2. 从当前集合中寻找一个子集 ,使得这个子集中的 的值最大。

输入

第一行为一个整数 ,接下来 行,每行要么是 ,要么是 ,如果是 ,则将 加入到集合中,否则为一次询问。 保证满足题意,且在第一个 之前至少存在一个 操作。

输出

对于每一次询问,输出询问的答案,误差在 以内即认为程序正确。

样例

输入 输出
6
1 3
2
1 4
2
1 8
2
0.0000000000
0.5000000000
3.0000000000
4
1 1
1 4
1 5
2
2.0000000000

题解

每次询问,贪心地选择最后加入的数字作为最大值,其他数字从前往后,只要加入某个数字 能够使得所有被选中的平均值下降,就可以选择这个值,因为序列是递增的,所以越往后选择的最大值,能选择的其他的数字一定越多,所以之前选过的数字在下一次询问中一定也会被选中,因此总的复杂度可以为

过题代码

  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 = 500000 + 100;
  20. int n, command, cnt, Index;
  21. double sum;
  22. double num[maxn];
  23. int main() {
  24. #ifdef Dmaxiya
  25. freopen("test.txt", "r", stdin);
  26. #endif // Dmaxiya
  27. ios::sync_with_stdio(false);
  28. while(scanf("%d", &n) != EOF) {
  29. Index= 0;
  30. cnt = 0;
  31. double sum = 0;
  32. for(int i = 1; i <= n; ++i) {
  33. scanf("%d", &command);
  34. if(command == 1) {
  35. ++cnt;
  36. scanf("%lf", &num[cnt]);
  37. } else {
  38. while((sum + num[cnt]) / (Index + 1) > num[Index + 1]) {
  39. ++Index;
  40. sum += num[Index];
  41. }
  42. printf("%.10f\n", num[cnt] - (sum + num[cnt]) / (Index + 1));
  43. }
  44. }
  45. }
  46. return 0;
  47. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注