比赛链接:传送门

A. Make a triangle!(简单思维)

题目大意:

给你三条边,问你最多加多少长度能使这三条边能构成三角形。

思路:

最大边小于答案加另外两条边的和。

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. int main()
  6. {
  7. int a, b, c;
  8. cin >> a >> b >> c;
  9. int _max = max(a, b);
  10. _max = max(_max, c);
  11. int sum = a+b+c - _max;
  12. int ans = max(, _max-sum+);
  13. cout << ans << endl;
  14. return ;
  15. }

B. Equations of Mathematical Magic(位运算)

题目大意:

给定a,求方程:a = x + (a^x)的非负整数解的数量。(符号"^"表示异或)

思路:

只有一个二进制位时:(表达式各位置的对应未知数与上面方程对齐)

① a = 0:0 = 0 + (0^0)

② a = 1:1 = 0 + (1^0) = 1 + (1^1)

所以对于题目a的每个二进制位:

① 如果为0,则x的对应二进制位也只能为0

② 如果为1,则x的对应二进制位可以是1或0

组合后答案为2k,(其中k为a变成二进制后1的个数)

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. int main()
  6. {
  7. int T;
  8. cin >> T;
  9. while (T--) {
  10. int N;
  11. cin >> N;
  12. int cnt = ;
  13. while (N) {
  14. if (N&)
  15. cnt++;
  16. N/=;
  17. }
  18. cout << ( << cnt) << endl;
  19. }
  20. return ;
  21. }
  22. /*
  23. 3
  24. 0
  25. 2
  26. 1073741823
  27. */

C. Oh Those Palindromes(字符串)

题目大意:

求给定字符串重排序后,最多的回文子串数量。

思路:

把一样的字母放在一起貌似就可以了。(直接sort)

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. int cnt[];
  6.  
  7. int main()
  8. {
  9. int N;
  10. string s;
  11. cin >> N >> s;
  12. memset(cnt, , sizeof cnt);
  13. for (int i = ; i < N; i++) {
  14. int ind = s[i] - 'a';
  15. cnt[ind]++;
  16. }
  17. for (int i = ; i < ; i++) {
  18. while (cnt[i]--) {
  19. printf("%c", 'a'+i);
  20. }
  21. }
  22. printf("\n");
  23. return ;
  24. }

D. Labyrinth(0-1bfs)

题目大意:

给定bfs图,起始点,最多的左移次数X、右移次数Y,求能访问的最多的格子数。

思路:

用bfs乍一搜可以pretest passed,但是可以被这组样例hack。

  1. /*
  2. 20 7
  3. 3 6
  4. 5 2
  5. ......*
  6. .****.*
  7. .****.*
  8. ....*.*
  9. **.**.*
  10. **.**.*
  11. **.**.*
  12. **.**.*
  13. **.**.*
  14. **.**.*
  15. **.**.*
  16. **.**.*
  17. **.**.*
  18. **.**.*
  19. **.**.*
  20. **.**.*
  21. **.**.*
  22. **.**.*
  23. **....*
  24. *******
  25. */

加一个对当前点X、Y的最大值的维护即可。

另外可以按列缩点跑最短路,不过我没试过。

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4. const int MAX_N = 2e3 + ;
  5. const int actx[] = {, , , -};
  6. const int acty[] = {, -, , };
  7.  
  8. struct Node{
  9. int x, y;
  10. int resl, resr;
  11. Node(int xx = , int yy = , int ll = , int rr = ) : x(xx), y(yy), resl(ll), resr(rr) {}
  12. }nodes[MAX_N][MAX_N];
  13.  
  14. int N, M, R, C, X, Y;
  15. char mat[MAX_N][MAX_N];
  16. bool vis[MAX_N][MAX_N];
  17.  
  18. inline bool check(int x, int y)
  19. {
  20. if (x < || x > N || y < || y > M)
  21. return false;
  22. if (mat[x][y] == '*')
  23. return false;
  24. return true;
  25. }
  26.  
  27. int main()
  28. {
  29. cin >> N >> M >> R >> C >> X >> Y;
  30. memset(vis, false, sizeof vis);
  31. for (int i = ; i <= N; i++)
  32. scanf("%s", mat[i]+);
  33.  
  34. queue <Node> Q;
  35. vis[R][C] = true;
  36. Q.push(Node(R, C, X, Y));
  37. while (!Q.empty()) {
  38. Node cur = Q.front(); Q.pop();
  39. for (int i = ; i < ; i++) {
  40. int x = cur.x + actx[i];
  41. int y = cur.y + acty[i];
  42. if (!check(x, y))
  43. continue;
  44. int l = cur.resl;
  45. int r = cur.resr;
  46. if (i == )
  47. r--;
  48. if (i == )
  49. l--;
  50. if (l < || r < )
  51. continue;
  52. if (x == && y == )
  53. int aaa = ;
  54. if (vis[x][y]) {
  55. if (l > nodes[x][y].resl || r > nodes[x][y].resr) {
  56. nodes[x][y].resl = max(l, nodes[x][y].resl);
  57. nodes[x][y].resr = max(r, nodes[x][y].resr);
  58. }
  59. else
  60. continue;
  61. }
  62. else if (!vis[x][y]) {
  63. nodes[x][y] = Node(x, y, l, r);
  64. vis[x][y] = true;
  65. }
  66. Q.push(Node(x, y, l, r));
  67. }
  68. }
  69. int ans = ;
  70. for (int i = ; i <= N; i++) {
  71. for (int j = ; j <= M; j++) {
  72. if (vis[i][j])
  73. ans++;
  74. }
  75. }
  76. cout << ans << endl;
  77. return ;
  78. }

更新:

正解应该是0-1bfs(说白了就是用双向队列deque维护的bfs)

纵向搜到的点入队首,横向搜到的点入队尾。

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4. const int MAX_N = + ;
  5. const int actx[] = {, -, , };
  6. const int acty[] = {, , , -};
  7. #define nx cur.x+actx[i]
  8. #define ny cur.y+acty[i]
  9.  
  10. struct Node{
  11. int x, y;
  12. int l, r;
  13. Node (int xx = , int yy = , int ll = , int rr = ) : x(xx), y(yy), l(ll), r(rr) {}
  14. };
  15.  
  16. int N, M, R, C, X, Y;
  17. bool vis[MAX_N][MAX_N];
  18. char mat[MAX_N][MAX_N];
  19.  
  20. bool check(int x, int y)
  21. {
  22. if (x < || x > N || y < || y > M)
  23. return false;
  24. if (mat[x][y] == '*' || vis[x][y])
  25. return false;
  26. return true;
  27. }
  28.  
  29. int bfs0_1()
  30. {
  31. int ans = ;
  32. memset(vis, false, sizeof vis);
  33. deque <Node> Q;
  34. Q.push_back(Node(R, C, X, Y));
  35. vis[R][C] = true;
  36. while (!Q.empty()) {
  37. Node cur = Q.front(); Q.pop_front();
  38. for (int i = ; i < ; i++) {
  39. if (!check(nx, ny))
  40. continue;
  41. int l = cur.l;
  42. int r = cur.r;
  43. if (i < ) {
  44. Q.push_front(Node(nx, ny, l, r));
  45. }
  46. else {
  47. if (i == )
  48. r--;
  49. if (i == )
  50. l--;
  51. if (l < || r < )
  52. continue;
  53. Q.push_back(Node(nx, ny, l, r));
  54. }
  55. vis[nx][ny] = true;
  56. ans++;
  57. }
  58. }
  59. return ans;
  60. }
  61.  
  62. int main()
  63. {
  64. cin >> N >> M >> R >> C >> X >> Y;
  65. for (int i = ; i <= N; i++)
  66. scanf("%s", mat[i]+);
  67. cout << bfs0_1() << endl;
  68.  
  69. return ;
  70. }

E. Dwarves, Hats and Extrasensory Abilities(二分)

题目大意:

交互式的题目,给定N,然后你输出N个点的坐标,你每输出一个点,他给你这个点的颜色(随机黑或白),然后让你给出一条直线,使得黑白的点在线的两边。

思路:

二分坐标系。注意题目中坐标系的上限直接拿来用的话,不够N的最大值。

所以有下图的二分选择:

注意交互式的题目输出时要加一个cout << flush;

  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. int main()
  6. {
  7. int N;
  8. cin >> N;
  9. int l = , r = << ;
  10. string sl, scur;
  11. cout << l << ' ' << l << endl << flush;
  12. cin >> sl;
  13. if (N == ) {
  14. cout << << ' ' << << endl << flush;
  15. cout << << ' ' << << endl << flush;
  16. return ;
  17. }
  18. cout << r << ' ' << << endl << flush;
  19. cin >> scur;
  20. N -= ;
  21. if (sl == scur) {//在(2^29, 0)到(2^29, 2^29)内二分
  22. int mid = (l + r) >> ;
  23. int x = << ;
  24. while (N--) {
  25. cout << x << ' ' << mid << endl << flush;
  26. cin >> scur;
  27. if (scur == sl)
  28. l = mid;
  29. else
  30. r = mid;
  31. mid = (l + r) >> ;
  32. }
  33. cout << x << ' ' << mid << endl << flush;
  34. cout << x- << ' ' << mid << endl << flush;
  35. }
  36. else {
  37. int mid = (l+r) >> ;
  38. int y = ;
  39. while (N--) {
  40. cout << mid << ' ' << y << endl << flush;
  41. cin >> scur;
  42. if (sl == scur) {
  43. l = mid;
  44. }
  45. else {
  46. r = mid;
  47. }
  48. mid = (l+r) >> ;
  49. }
  50. cout << mid << ' ' << y << endl << flush;
  51. cout << mid << ' ' << y+ << endl << flush;
  52. }
  53. return ;
  54. }

更新:

在x轴上二分也可以。

  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. void print(int x, int y)
  6. {
  7. cout << x << ' ' << y << endl << flush;
  8. }
  9.  
  10. int main()
  11. {
  12. int N;
  13. string col, pre;
  14. cin >> N;
  15. int l = , mid = , r = <<;
  16. if (N--) {
  17. print(l, );
  18. cin >> pre;
  19. mid = (l+r) >> ;
  20. }
  21. while (N--) {
  22. print(mid, );
  23. cin >> col;
  24. if (col == pre)
  25. l = mid;
  26. else
  27. r = mid;
  28. mid = (l+r) >> ;
  29. }
  30. print(l, );
  31. print(r, );
  32. return ;
  33. }

F. Candies for Children(数学+分类暴力)

题目大意:

有n个人围成一圈分k个糖果,从 l 开始分到 r ,可以跑很多圈。一个人拿一颗,里面有p个人喜欢甜食会拿两颗。

问你p的最大值。数据矛盾则输出-1。

思路:

题目中的数据范围是1e11,这个数据很微妙(1e11 = 1e5 * 1e6),所以分两种情况讨论:

① n < 2e6 :

   这时候可以直接跑答案。

  对于给定的p,y有很多取值,但是可以直接取模算出y的满足p、d约束最大值。O(n)复杂度。

② n > 2e6 :

   这时候跑圈数i,每个对应的圈数可以求出最大的喜欢甜食的人数:

  1、(p + n) * i + y + d = k

  2、p - y <= n - d

  联立这个就可以求p的最大值。(其中d表示l跑到r的人数,y表示d中的喜甜人数)然后处理一下细节就可以O(k/n)。

  然后暴力跑就好了。注意一个点就是最后一个人可以喜欢甜食但是只拿一个。

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4. typedef long long ll;
  5. const ll X = 2e6 + ;
  6.  
  7. int main()
  8. {
  9. ll n, l, r, k;
  10. cin >> n >> l >> r >> k;
  11. ll d = (r - l + n) % n + ;
  12.  
  13. ll ans = -;
  14. if (n < X) {
  15. for (ll p = n; p >= ; p--) {
  16. ll y = (k - )%(n + p) + - d;
  17. if (y < || y > p || y > d || d-(y+) > n-p)
  18. continue;
  19. ll y2 = y+;
  20. if (y2 <= p && y2 <= d) {
  21. ans = max(ans , p);
  22. }
  23. if (d-y <= n-p) {
  24. ans = max(ans, p);
  25. }
  26. }
  27. }
  28. else {
  29. for (ll i = ; i <= k/n; i++) {
  30. ll p = (k - *d - (i-)*n + ) / (i+);
  31. ll y = k - i*(n+p) - d;
  32. if (y < ) {
  33. if (i == )
  34. continue;
  35. ll dis = (-y - ) / i + ;
  36. y += i*dis;
  37. p -= dis;
  38. }
  39. if (p > n) {
  40. y += (p-n) * i;
  41. p == n;
  42. }
  43. if (y < || y > p || y > d || d-(y+) > n-p)
  44. continue;
  45. ll y2 = y+;
  46. if (y2 <= p && y2 <= d) {
  47. ans = max(ans , p);
  48. }
  49. if (d-y <= n-p) {
  50. ans = max(ans, p);
  51. }
  52. }
  53. }
  54. cout << ans << endl;
  55. return ;
  56. }
  57. /*
  58. 10 5 5 1
  59. 10000000 5 5 1
  60. */

Codeforces Round #516(Div 2)的更多相关文章

  1. Codeforces Round #516 (Div. 2)D. Labyrinth(BFS)

    题目链接:http://codeforces.com/contest/1064/problem/D 题目大意:给你一个n*m的图,图中包含两种符号,'.'表示可以行走,'*'表示障碍物不能行走,规定最 ...

  2. Codeforces Round #516 (Div. 2, by Moscow Team Olympiad) D. Labyrinth

    http://codeforces.com/contest/1064/problem/D 向上/向下加0,向左/右加1, step = 0,1,…… 求的是最少的步数,所以使用bfs. step=k ...

  3. Codeforces Round #516 (Div. 2) (A~E)

    目录 Codeforces 1064 A.Make a triangle! B.Equations of Mathematical Magic C.Oh Those Palindromes D.Lab ...

  4. Codeforces Round #516 (Div. 2, by Moscow Team Olympiad) D. Labyrinth(重识搜索)

    https://codeforces.com/contest/1064/problem/D 题意 给你一个有障碍的图,限制你向左向右走的次数,问你可以到达格子的个数 思路 可以定义状态为vi[x][y ...

  5. Codeforces Round #516 (Div. 2)D. Labyrinth

    D. Labyrinth 题目链接:https://codeforces.com/contest/1064/problem/D 题意: 给出一个n*m的矩阵以及人物的起点,并且给出x,y,分别代表这个 ...

  6. Codeforces Round #516 (Div. 2, by Moscow Team Olympiad)

    题目链接 A. Make a triangle! 题意 让某段最少增加多少使得构成三角形 思路 让较小两段往最长段去凑 代码 #include <bits/stdc++.h> #defin ...

  7. Codeforces Round#516 Div.1 翻车记

    A:开场懵逼.然后发现有人1min过,于是就sort了一下,于是就过了.正经证明的话,考虑回文串两端点一定是相同的,所以最多有Σcnti*(cnti+1)/2个,cnti为第i种字母出现次数.而sor ...

  8. [Codeforces Round #516 (Div. 2, by Moscow Team Olympiad) ](A~E)

    A: 题目大意:给你$a,b,c$三条边,可以给任意的边加任意的长度,求最少共加多少长度使得可以构成三角形 题解:排个序,若可以组成,输出$0$,否则输出$c-a-b+1(设a\leqslant b\ ...

  9. Codeforces Round #366 (Div. 2) ABC

    Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...

随机推荐

  1. python中字典内置方法

  2. Java Web(十二) JavaMail发送邮件

    发送邮件的原理 概叙 邮件服务器: 要在 Internet 上提供电子邮件功能,必须有专门的电子邮件服务器.例如现在 Internet 很多 提供邮件服务的厂商:sina.sohu.163 等等他们都 ...

  3. 启动项目时出现java.io.EOFException异常。

    错误: 2018-4-18 10:55:54 org.apache.catalina.session.StandardManager doLoad 严重: IOException while load ...

  4. 数据泵导入 ORA-31626

    Oracle,10G,数据泵导入时,报错如下: 解决方案:对当前用户做如下授权 . 具体操作:grant connect,resource to user;

  5. poj3261

    题解: 同bzoj1717 代码: #include<bits/stdc++.h> using namespace std; ,P2=,P=; int a1[P],num[P],a2[P] ...

  6. 51nod算法马拉松B

    首先将原本字符串hash,注意每一个字母要分开了. 然后并查集判断字符相同,将字符ascll吗乘转化为祖先乘. 然后就可以判断相等的情况. 然后考虑相等的情况. 二分枚举中间点,然后如果左边是不相等并 ...

  7. java语句的控制流程

    if(布尔表达式 ){ 程序执行语句1 }else { 程序执行语句2 } while(布尔表达式){ 程序执行语句 } do{ 程序执行语句 }while(布尔表达式); for(初始化语句,条件语 ...

  8. Android开发---如何操作资源目录中的资源文件

    效果图: 1.activity_main.xml <?xml version="1.0" encoding="utf-8"?> <Linear ...

  9. ln -s 软连接

    创建软连接 ln -s 我们通过实例查看ls的路径发现,在/tmp/目录下的/bin/ls指向的是/usr/bin/ls,所以这里/tmp/bin/ls所存储的就是一个绝对路径,我们可以看做是一个软链 ...

  10. matlab中的reshape快速理解,卷积和乘积之间的转换

    reshape: THe convertion between convolution and multiplication: