Codeforces Round #264 (Div. 2)

举报
Linux猿 发表于 2021/08/04 23:00:51 2021/08/04
【摘要】 Codeforces 463C Gargari and Bishops 做题感悟:                  好不容易见到一场CF时间在15:30 比的就做了一下,第一题题意多了老半天没读懂 ,然后丢下第一题果断做第二题,第二题提议好理解,但是感觉太简单了,不敢相...

Codeforces 463C Gargari and Bishops

做题感悟:

                 好不容易见到一场CF时间在15:30 比的就做了一下,第一题题意多了老半天没读懂快哭了 ,然后丢下第一题果断做第二题,第二题提议好理解,但是感觉太简单了,不敢相信,于是就抱着试一试的想法提交了一下预测通过,回头做第一题理解了题意提交预测通过,但是悲剧的是不一会就被hack 了 ,又看了代码才发现少了一种情况。第三题读懂题意后还没写完代码就结束比赛了,还好前两题最后都AC了。

解题思路:

                在棋盘上放置两个象,象攻击的到的地方为象所在的方格的对角线,但是两个象不能攻击同一个格子且使所有攻击到的格子的和最大。这里要注意副对角线上 x + y 是递增 ,主对角线上处理一下也可以是递增的,这样两条对角线上的数都预处理出来了,这样就剩处理两个象不能同时攻击一个格子,这里只要分开坐标和(x+y)奇偶就可以,然后找到奇偶的最大值就可以了。

代码:


  
  1. #include<iostream>
  2. #include<cstring>
  3. #include<cstdio>
  4. #include<algorithm>
  5. using namespace std ;
  6. #define INT __int64
  7. const int MX = 2000 + 10 ;
  8. const int MY = 10000 + 10 ;
  9. INT n ;
  10. INT g[MX][MX] ,L[MY] ,R[MY] ;
  11. void input()
  12. {
  13. memset(g ,0 ,sizeof(g)) ;
  14. memset(L ,0 ,sizeof(L)) ;
  15. memset(R ,0 ,sizeof(R)) ;
  16. for(INT i = 1 ;i <= n ; ++i)
  17. for(INT j = 1 ;j <= n ; ++j)
  18. {
  19. scanf("%I64d" ,&g[i][j]) ;
  20. L[i+j] += g[i][j] ;
  21. R[i-j+n*2+5] += g[i][j] ;
  22. }
  23. }
  24. void solve()
  25. {
  26. INT MR = 0 ,ML = 0 ,ax = 1 ,ay = 1 ,bx = 1 ,by = 2 ;
  27. for(INT i = 1 ;i <= n ; ++i)
  28. for(INT j = 1 ;j <= n ; ++j)
  29. if((i+j)%2)
  30. {
  31. if(L[i+j]+R[i-j+n*2+5]-g[i][j] > ML)
  32. {
  33. ML = L[i+j]+R[i-j+n*2+5]-g[i][j] ;
  34. bx = i ;
  35. by = j ;
  36. }
  37. }
  38. else
  39. {
  40. if(L[i+j]+R[i-j+n*2+5]-g[i][j]>MR)
  41. {
  42. MR = L[i+j]+R[i-j+n*2+5]-g[i][j] ;
  43. ax = i ;
  44. ay = j ;
  45. }
  46. }
  47. cout<<MR+ML<<endl ;
  48. cout<<ax<<" "<<ay<<" "<<bx<<" "<<by<<endl ;
  49. }
  50. int main()
  51. {
  52. while(~scanf("%I64d" ,&n))
  53. {
  54. input() ;
  55. solve() ;
  56. }
  57. return 0 ;
  58. }
Codeforces 463D Gargari and Permutations

解题思路:因为 k 很小,如果在每个序列中 i 都在 j 前面我们就认为 i 到 j  有一条有向边,这样一处理,然后记忆话搜索一下就ok了。

代码:


  
  1. #include<iostream>
  2. #include<fstream>
  3. #include<vector>
  4. #include<sstream>
  5. #include<cstring>
  6. #include<cstdio>
  7. #include<algorithm>
  8. using namespace std ;
  9. #define INT __int64
  10. const int MX = 1000 + 10 ;
  11. const int MY = 10000 + 10 ;
  12. int n ,m ;
  13. bool vis[MX][MX] ;
  14. int g[10][MX] ,dp[MX] ;
  15. void input()
  16. {
  17. int x ;
  18. memset(g ,0 ,sizeof(g)) ;
  19. memset(vis ,false ,sizeof(vis)) ;
  20. for(int i = 0 ;i < m ; ++i)
  21. for(int j = 1 ; j <= n ; ++j)
  22. {
  23. scanf("%d" ,&x) ;
  24. g[i][x] = j ;
  25. }
  26. for(int i = 1 ;i <= n ; ++i)
  27. {
  28. vis[0][i] = true ;
  29. for(int j = 1 ;j <= n ; ++j)
  30. if(i != j)
  31. {
  32. bool flag = true ;
  33. for(int k = 0 ;k < m ; ++k)
  34. if(g[k][i] > g[k][j])
  35. {
  36. flag = false ;
  37. break ;
  38. }
  39. vis[i][j] = flag ;
  40. }
  41. }
  42. }
  43. int DP_Memory(int x)
  44. {
  45. if(dp[x] != -1) return dp[x] ;
  46. int& ans = dp[x] ;
  47. ans = 0 ;
  48. for(int i = 1 ;i <= n ; ++i)
  49. if(vis[x][i])
  50. ans = max(ans ,DP_Memory(i)) ;
  51. ans++ ;
  52. return ans ;
  53. }
  54. int main()
  55. {
  56. while(~scanf("%d%d" ,&n ,&m))
  57. {
  58. input() ;
  59. memset(dp ,-1 ,sizeof(dp)) ;
  60. cout<<DP_Memory(0)-1<<endl ;
  61. }
  62. return 0 ;
  63. }

Codeforces 463E Caisa and Tree

做题感悟:比赛时根本就没看到这题,其实看到也做不出来,做题的时候应该发现突破点,就拿这题来说突破点是改变某个点的价值不会超过 50 次,同时发现应该加强自己的C++ 一些容器的运用。

解题思路:

                上面已经说到本题的突破点是 50 ,so ~> 我们可以每次改变某个点的价值的时候重新预处理一下 ,这样最多预处理 50 次。那么接下来就解决怎样预处理的问题了,这里因为第一问求的是每个点距离此点最近的且最大公约数大于 1 的节点 ,所以我们可以分解素数,把每一个节点的 value 都分解了,DFS找一个深度最深的且与当前节点有公共素因子的节点 就可以了。

代码:


  
  1. #include<iostream>
  2. #include<sstream>
  3. #include<map>
  4. #include<cmath>
  5. #include<fstream>
  6. #include<vector>
  7. #include<sstream>
  8. #include<cstring>
  9. #include<cstdio>
  10. #include<conio.h>
  11. #include<stack>
  12. #include<bitset>
  13. #include<ctime>
  14. #include<cstring>
  15. #include<algorithm>
  16. using namespace std ;
  17. #define INT __int64
  18. const int MP = 2000000 + 5 ;
  19. const int MY = 150000 + 5 ;
  20. const int MX = 100000 + 5 ;
  21. int n ,m ;
  22. bool isprime[MP] ;
  23. int pos[MP] ,prime[MY] ,value[MX] ,ans[MX] ,niv[MX] ;
  24. vector<int> G[MX] ;
  25. stack<int> s[MY] ;
  26. void InitPrime() // 筛选素数
  27. {
  28. int num = 0 ;
  29. memset(isprime ,false ,sizeof(isprime)) ;
  30. for(int i = 2 ;i < MP ; ++i)
  31. {
  32. if(!isprime[i])
  33. {
  34. prime[++num] = i ;
  35. pos[i] = num ;
  36. }
  37. for(int j = 1 ;j <= num && prime[j]*i < MP-5 ; ++j)
  38. {
  39. isprime[i*prime[j]] = true ;
  40. if(i % prime[j] == 0)
  41. break ;
  42. }
  43. }
  44. }
  45. void input()
  46. {
  47. int x ,y ;
  48. for(int i = 1 ;i <= n ; ++i)
  49. {
  50. scanf("%d" ,&value[i]) ;
  51. G[i].clear() ;
  52. }
  53. for(int i = 1 ;i < n ; ++i)
  54. {
  55. scanf("%d%d" ,&x ,&y) ;
  56. G[x].push_back(y) ;
  57. G[y].push_back(x) ;
  58. }
  59. }
  60. void DFS(int node ,int father)
  61. {
  62. vector<int> v ;
  63. int x = value[node] ;
  64. int d = 2 ,step = 1 ;
  65. ans[node] = 0 ;
  66. while(d*d <= x)
  67. {
  68. if(!(x%d))
  69. {
  70. if(!s[pos[d]].empty())
  71. {
  72. int y = s[pos[d]].top() ;
  73. if(niv[y] > niv[ans[node]])
  74. ans[node] = y ;
  75. }
  76. v.push_back(pos[d]) ;
  77. s[pos[d]].push(node) ;
  78. while(x%d == 0)
  79. {
  80. x /= d ;
  81. }
  82. }
  83. ++step ;
  84. d = prime[step] ;
  85. }
  86. if(x > 1)
  87. {
  88. if(!s[pos[x]].empty())
  89. {
  90. int y = s[pos[x]].top() ;
  91. if(niv[y] > niv[ans[node]])
  92. ans[node] = y ;
  93. }
  94. v.push_back(pos[x]) ;
  95. s[pos[x]].push(node) ;
  96. }
  97. for(int i = 0 ; i < G[node].size() ; ++i)
  98. if(G[node][i] != father)
  99. {
  100. int y = G[node][i] ;
  101. niv[y] = niv[node] + 1 ;
  102. DFS(y , node) ;
  103. }
  104. for(int i = 0 ;i < v.size() ; ++i)
  105. s[v[i]].pop() ;
  106. v.clear() ;
  107. }
  108. int main()
  109. {
  110. int p ,x ,w ;
  111. InitPrime() ;
  112. while(~scanf("%d%d" ,&n ,&m))
  113. {
  114. input() ;
  115. niv[1] = 1 ;
  116. DFS(1 ,-1) ;
  117. while(m--)
  118. {
  119. scanf("%d%d" ,&p ,&x) ;
  120. if(p == 1)
  121. cout<<(ans[x] > 0 ? ans[x] : -1)<<endl ;
  122. else
  123. {
  124. scanf("%d" ,&w) ;
  125. value[x] = w ;
  126. DFS(1 ,-1) ;
  127. }
  128. }
  129. }
  130. return 0 ;
  131. }



 

文章来源: blog.csdn.net,作者:Linux猿,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/nyist_zxp/article/details/38958505

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。