当前位置:   article > 正文

codeforces792C 2000分 分类讨论

codeforces792C 2000分 分类讨论

题目传送门

题意:

没有前导0的n位十进制数,让你去掉尽可能少的若干位,使剩余十进制数是3的倍数。

限制:剩余的数不能有前导0,但可以是0。

数据范围:\dpi1501n105 。

题解:

一个数是3的倍数,那么该数的十进制位累加后是3的倍数。

数论知识就用到了上面这句话,然后就是下面的分类讨论。

(1)如果这个数是3的倍数,那么不变就行了。

(2)如果这个数模3余1,那么你删除靠后的1个1或者2个2,比较一下删除哪一个剩余位数更大。

(3)如果这个数模3余2,那么你删除靠后的1个2或者2个1,比较一下删除哪一个剩余位数更大。

注意:考虑前导0,以及考虑剩余数为0。

感受:

细节考虑有问题,以及少考虑一种情况 。

一直在面向数据编程。

虽说我是看数据修改过后才过的,但是我不懂这道题为什么有2000分,1600分差不多吧。

一点也不难,就是分类讨论一下就好。

代码: 

  1. #include<bits/stdc++.h>
  2. using namespace std ;
  3. typedef long long ll ;
  4. typedef pair<int , int> pii ;
  5. const int maxn = 1e5 + 5 ;
  6. int len , num[5] ;
  7. int sum = 0 ;
  8. char s[maxn] ;
  9. bool vis[maxn] ;
  10. bool wujie()
  11. {
  12. if(num[0] + num[3] > 0) return 0 ;
  13. if(num[1] >= 3 || num[2] >= 3) return 0 ;
  14. if(num[1] >= 1 && num[2] >= 1) return 0 ;
  15. return 1 ;
  16. }
  17. int djian1()
  18. {
  19. bool flag = 0 ;
  20. int cnt = 0 ;
  21. if(num[1] == 0) return -1 ;
  22. memset(vis , 0 , sizeof(vis)) ;
  23. for(int i = len - 1 ; i >= 0 ; i --)
  24. if((s[i] - '0') % 3 == 1) {vis[i] = 1 ; break ;}
  25. for(int i = 0 ; i < len ; i ++)
  26. {
  27. if(vis[i] || !flag && s[i] == '0') continue ;
  28. flag = 1 ;
  29. cnt ++ ;
  30. }
  31. return cnt ;
  32. }
  33. void ddojian1()
  34. {
  35. int cnt = 0 ;
  36. bool flag = 0 ;
  37. memset(vis , 0 , sizeof(vis)) ;
  38. for(int i = len - 1 ; i >= 0 ; i --)
  39. if((s[i] - '0') % 3 == 1) {vis[i] = 1 ; break ;}
  40. for(int i = 0 ; i < len ; i ++)
  41. {
  42. if(vis[i] || !flag && s[i] == '0') continue ;
  43. flag = 1 ;
  44. printf("%c" , s[i]) ;
  45. }
  46. if(!flag) printf("0") ;
  47. printf("\n") ;
  48. }
  49. int djian2()
  50. {
  51. int cnt = 0 ;
  52. bool flag = 0 ;
  53. int cas = 2 ;
  54. if(num[2] < 2) return -1 ;
  55. memset(vis , 0 , sizeof(vis)) ;
  56. for(int i = len - 1 ; i >= 0 ; i --)
  57. {
  58. if((s[i] - '0') % 3 == 2) vis[i] = 1 , cas -- ;
  59. if(cas == 0) break ;
  60. }
  61. for(int i = 0 ; i < len ; i ++)
  62. {
  63. if(vis[i] || !flag && s[i] == '0') continue ;
  64. flag = 1 ;
  65. cnt ++ ;
  66. }
  67. return cnt ;
  68. }
  69. void ddojian2()
  70. {
  71. int cnt = 0 ;
  72. bool flag = 0 ;
  73. int cas = 2 ;
  74. memset(vis , 0 , sizeof(vis)) ;
  75. for(int i = len - 1 ; i >= 0 ; i --)
  76. {
  77. if((s[i] - '0') % 3 == 2) vis[i] = 1 , cas -- ;
  78. if(cas == 0) break ;
  79. }
  80. for(int i = 0 ; i < len ; i ++)
  81. {
  82. if(vis[i] || !flag && s[i] == '0') continue ;
  83. flag = 1 ;
  84. printf("%c" , s[i]) ;
  85. }
  86. if(!flag) printf("0") ;
  87. printf("\n") ;
  88. }
  89. void solve1()
  90. {
  91. int x = djian2() ;
  92. int y = djian1() ;
  93. if(x >= y) ddojian2() ;
  94. else ddojian1() ;
  95. }
  96. int jian2()
  97. {
  98. bool flag = 0 ;
  99. int cnt = 0 ;
  100. if(num[2] == 0) return -1 ;
  101. memset(vis , 0 , sizeof(vis)) ;
  102. for(int i = len - 1 ; i >= 0 ; i --)
  103. if((s[i] - '0') % 3 == 2) {vis[i] = 1 ; break ;}
  104. for(int i = 0 ; i < len ; i ++)
  105. {
  106. if(vis[i] || !flag && s[i] == '0') continue ;
  107. flag = 1 ;
  108. cnt ++ ;
  109. }
  110. return cnt ;
  111. }
  112. void dojian2()
  113. {
  114. int cnt = 0 ;
  115. bool flag = 0 ;
  116. memset(vis , 0 , sizeof(vis)) ;
  117. for(int i = len - 1 ; i >= 0 ; i --)
  118. if((s[i] - '0') % 3 == 2) {vis[i] = 1 ; break ;}
  119. for(int i = 0 ; i < len ; i ++)
  120. {
  121. if(vis[i] || !flag && s[i] == '0') continue ;
  122. flag = 1 ;
  123. printf("%c" , s[i]) ;
  124. }
  125. if(!flag) printf("0") ;
  126. printf("\n") ;
  127. }
  128. int jian1()
  129. {
  130. int cnt = 0 ;
  131. bool flag = 0 ;
  132. int cas = 2 ;
  133. if(num[1] < 2) return -1 ;
  134. memset(vis , 0 , sizeof(vis)) ;
  135. for(int i = len - 1 ; i >= 0 ; i --)
  136. {
  137. if((s[i] - '0') % 3 == 1) vis[i] = 1 , cas -- ;
  138. if(cas == 0) break ;
  139. }
  140. for(int i = 0 ; i < len ; i ++)
  141. {
  142. if(vis[i] || !flag && s[i] == '0') continue ;
  143. flag = 1 ;
  144. cnt ++ ;
  145. }
  146. return cnt ;
  147. }
  148. void dojian1()
  149. {
  150. int cnt = 0 ;
  151. bool flag = 0 ;
  152. int cas = 2 ;
  153. memset(vis , 0 , sizeof(vis)) ;
  154. for(int i = len - 1 ; i >= 0 ; i --)
  155. {
  156. if((s[i] - '0') % 3 == 1) vis[i] = 1 , cas -- ;
  157. if(cas == 0) break ;
  158. }
  159. for(int i = 0 ; i < len ; i ++)
  160. {
  161. if(vis[i] || !flag && s[i] == '0') continue ;
  162. flag = 1 ;
  163. printf("%c" , s[i]) ;
  164. }
  165. if(!flag) printf("0") ;
  166. printf("\n") ;
  167. }
  168. void solve2()
  169. {
  170. int x = jian2() ;
  171. int y = jian1() ;
  172. if(x >= y) dojian2() ;
  173. else dojian1() ;
  174. }
  175. int main()
  176. {
  177. scanf("%s" , s) ;
  178. len = strlen(s) ;
  179. memset(num , 0 , sizeof(num)) ;
  180. memset(vis , 0 , sizeof(vis)) ;
  181. for(int i = 0 ; i < len ; i ++)
  182. {
  183. int x = s[i] - '0' ;
  184. sum += x , sum %= 3 ;
  185. if(x == 0){num[0] ++ ; continue ;}
  186. x %= 3 ;
  187. if(x == 0) x = 3 ;
  188. num[x] ++ ;
  189. }
  190. if(wujie()) printf("-1\n") ;
  191. else if(sum == 0) printf("%s\n" , s) ;
  192. else if(sum == 1) solve1() ;
  193. else solve2() ;
  194. return 0 ;
  195. }

 

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号