1. /**
  2. 题目:C. Divide by Six
  3. 链接:https://oj.ejq.me/problem/24
  4. 题意:给定一个数,这个数位数达到1e5,可能存在前导0.问为了使这个数是6的倍数,且没有前导0,删除尽量少的位数,可以任意位置删除。
  5. 输出剩余的位数。如果找不到,输出-1s。
  6. 思路:
  7. 一开始心想,这么多个位置,又不知道删除几个,排列组合的情况下,简直不可能完成。
  8. 这题是我的队友tzq想出来的。在此重新思考一下。
  9. 常规想法不可能完成。一定存在某些特殊的地方。观察题目要求,6的倍数。一个数是6的倍数有什么特殊性?
  10. 尾数一定是偶数。那么枚举尾数为偶数,仍然很大。
  11. 假设确定了一定是2的倍数,那么只要判断是否是3的倍数就行了。而判断一个数是否是3的倍数,只要各个数位的和是3的倍数这个数就一定是3的倍数。很容易证明。
  12.  
  13. 如果找到一个尾数为偶数,且从它为尾的数%3==0.那么这个可能是答案。
  14. %3==1.那么要删除一个某个位的数%3==1的位。或者删除两个数位上的数%3==2的位。为了避免删除后出现前导0,为了答案最优,从右边开始找。如果找不到,所以这种情况无解。
  15. 如果删除后出现前导0,去掉前导0,不会有影响。注意把数删完了的情况。此时无解。
  16. %3==2.那么删除一个某个位的数%3==2的位,或者删除两个数位上的数%3==1的位,同上。
  17.  
  18. 问题是:尾数为偶数有很多种情况。我们知道为了让剩余的位数越来越多。所以选择尾数为偶数应该尽量右才好。
  19. 如果某两个位作为尾数。以他们为尾数的数%3==0,则显然取尾数更右的更优。
  20. 同理%3==1, %3==2,都是选更右的更优,这样删除的选择更多,且剩余的数位也更多。
  21.  
  22. 至此,本体解法为分析+模拟。
  23. 细节:只要有前导0,肯定有答案。即剩余的数位0.那么输出1;
  24. */
  25. #include<bits/stdc++.h>
  26. #define LL long long
  27. using namespace std;
  28. typedef long long ll;
  29. const int maxn = 1e5+;
  30. char s[maxn];
  31. int r[maxn];
  32. int rr[maxn];
  33. char temp[maxn];
  34. int r0, r1, r2;///%3==0, %3==1, %3==2的尾数位置。
  35. int leadzero, len, ans;
  36. int getR(int type)
  37. {
  38. for(int i = len-; i>= ; i--){
  39. if(r[i]==type&&(s[i]-'')%==){
  40. return i;
  41. }
  42. }
  43. return -;
  44. }
  45. void f(int r,int type)
  46. {
  47. if(r==-) return ;
  48. ///type==1
  49. if(type==)
  50. {
  51. /// 删除一个1
  52. for(int i = r; i >= &&r>; i--){
  53. if(rr[i]==){
  54. if(i==){
  55. int t = i+;
  56. while(t<=r&&temp[t]==''){
  57. t++;
  58. }
  59. if(t>r){
  60. ans = max(ans,);
  61. }else
  62. {
  63. ans = max(ans,r-t+);
  64. }
  65. }else
  66. {
  67. ans = max(ans,r);
  68. }
  69. }
  70. }
  71. /// 删除两个2
  72. int cnt = , pos = -;
  73. char tt;
  74. for(int i = r; i >= &&r>; i--){
  75. if(rr[i]==){
  76. cnt--;
  77. if(cnt==){
  78. if(i==){
  79. int t = i+;
  80. while(t<=r&&temp[t]==''){
  81. t++;
  82. }
  83. if(t>r){
  84. ans = max(ans,);
  85. }else
  86. {
  87. ans = max(ans,r-t+);
  88. }
  89. }else
  90. {
  91. ans = max(ans,r);
  92. }
  93. }else
  94. {
  95. pos = i;
  96. tt = temp[i];
  97. temp[i]='';
  98. }
  99. }
  100. }
  101. if(pos!=-) temp[pos] = tt;
  102.  
  103. }else
  104. ///type==2
  105. {
  106. ///删除一个2
  107. for(int i = r; i >= &&r>; i--){
  108. if(rr[i]==){
  109. if(i==){
  110. int t = i+;
  111. while(t<=r&&temp[t]==''){
  112. t++;
  113. }
  114. if(t>r){
  115. ans = max(ans,);
  116. }else
  117. {
  118. ans = max(ans,r-t+);
  119. }
  120. }else
  121. {
  122. ans = max(ans,r);
  123. }
  124. }
  125. }
  126. ///删除两个1
  127. int cnt = , pos = -;
  128. char tt;
  129. for(int i = r; i >= &&r>; i--){
  130. if(rr[i]==){
  131. cnt--;
  132. if(cnt==){
  133. if(i==){
  134. int t = i+;
  135. while(t<=r&&temp[t]==''){
  136. t++;
  137. }
  138. if(t>r){
  139. ans = max(ans,);
  140. }else
  141. {
  142. ans = max(ans,r-t+);
  143. }
  144. }else
  145. {
  146. ans = max(ans,r);
  147. }
  148. }else
  149. {
  150. pos = i;
  151. tt = temp[i];
  152. temp[i]='';
  153. }
  154. }
  155. }
  156. if(pos!=-) temp[pos] = tt;
  157. }
  158. }
  159. int main()
  160. {
  161. while(scanf("%s",s)==)
  162. {
  163. r0 = r1 = r2 = -;
  164. leadzero = ;
  165. while(s[leadzero]!='\0'&&s[leadzero]==''){
  166. leadzero++;
  167. }
  168. if(s[leadzero]=='\0'){
  169. printf("1\n"); continue;
  170. }
  171. if(leadzero>) ans = ;///只要有前导0,那么肯定可以一个0作为结果。
  172. strcpy(temp,s+leadzero);
  173. // printf("temp = %s\n", temp);
  174. strcpy(s,temp);
  175. len = strlen(s);
  176. int p = ;
  177. for(int i = ; s[i]!='\0'; i++){
  178. p = p+(s[i]-'');
  179. p %= ;
  180. r[i] = p;
  181. rr[i] = (s[i]-'')%;
  182. }
  183. ans = -;
  184. r0 = getR();
  185. if(r0!=-) ans = r0+;
  186. r1 = getR();
  187. r2 = getR();
  188. f(r1,);
  189. //strcpy(temp,s);
  190. f(r2,);
  191. if(ans!=-){
  192. printf("%d\n",ans);
  193. }else printf("-1s\n");
  194. }
  195. return ;
  196. }

2017 Wuhan University Programming Contest (Online Round) C. Divide by Six 分析+模拟的更多相关文章

  1. 2017 Wuhan University Programming Contest (Online Round) Lost in WHU 矩阵快速幂 一个无向图,求从1出发到达n最多经过T条边的方法数,边可以重复经过,到达n之后不可以再离开。

    /** 题目:Lost in WHU 链接:https://oj.ejq.me/problem/26 题意:一个无向图,求从1出发到达n最多经过T条边的方法数,边可以重复经过,到达n之后不可以再离开. ...

  2. 2017 Wuhan University Programming Contest (Online Round) B Color 树形dp求染色方法数

    /** 题目:Color 链接:https://oj.ejq.me/problem/23 题意:给定一颗树,将树上的点最多染成m种颜色,有些节点不可以染成某些颜色.相邻节点颜色不同.求染色方法数. 思 ...

  3. 2017 Wuhan University Programming Contest (Online Round) D. Events,线段树区间更新+最值查询!

    D. Events 线段树区间更新查询区间历史最小值,看似很简单的题意写了两天才写出来. 题意:n个数,Q次操作,每次操作对一个区间[l,r]的数同时加上C,然后输出这段区间的历史最小值. 思路:在线 ...

  4. zoj 4020 The 18th Zhejiang University Programming Contest Sponsored by TuSimple - G Traffic Light(广搜)

    题目链接:The 18th Zhejiang University Programming Contest Sponsored by TuSimple - G Traffic Light 题解: 题意 ...

  5. The 16th Zhejiang University Programming Contest-

    Handshakes Time Limit: 2 Seconds      Memory Limit: 65536 KB Last week, n students participated in t ...

  6. 2017 Bangladesh National High School Programming Contest ( National Round, Senior Group ), NHSPC 2017 题解

    [题目链接] A. Charm Is Not Always Enough 模拟一下就可以了. #include <bits/stdc++.h> using namespace std; i ...

  7. The 18th Zhejiang University Programming Contest Sponsored by TuSimple

    Pretty Matrix Time Limit: 1 Second      Memory Limit: 65536 KB DreamGrid's birthday is coming. As hi ...

  8. 写完代码就去吃饺子|The 10th Henan Polytechnic University Programming Contest

    河南理工大学第十届校赛 很久没有组队打比赛了,好吧应该说很久没有写题了, 三个人一起玩果然比一个人玩有趣多了... 前100分钟过了4题,中途挂机100分钟也不知道什么原因,可能是因为到饭点太饿了?, ...

  9. The 15th Zhejiang University Programming Contest

    a  ZOJ 3860 求和大家不一样的那个数,签到,map水之 #include<cstdio> #include<map> using namespace std; map ...

随机推荐

  1. RxJava 1.x 理解-1

    先看下别人实现的最基本的RxJava的实现方式: 在RxJava里面,有两个必不可少的角色:Subscriber(观察者) 和 Observable(订阅源). Subscriber(观察者) Sub ...

  2. AppCompatActivity与toolbar的结合

    原文:http://www.51itong.net/android-activity-appcompatactivity-toolbar-15750.html 另外一个博客:Android 5.x T ...

  3. Linux下使用split按行数进行切割

    说明:一般来说split按行数切割多数用在日志文件上. 实例: 将一个大文件分成若干个小文件方法: 例如将一个BLM.txt文件分成前缀为BLM_ 的1000个小文件,后缀为系数形式,且后缀为4位数字 ...

  4. C#中Math的使用总结

    1.向上进位取整.Math.Ceiling 例如: Math.Ceiling(32.6)=33; Math.Ceiling(32.0)=32; 2.向下舍位取整.Math.Floor 例如: Math ...

  5. Shell中 调用/引用/包含 另外的脚本文件的两种方法

    脚本 first (测试示例1) #!/bin/bash echo 'your are in first file' 问)在当前脚本文件中调用另外一个脚本文件? 方法一: 使用 source 脚本 s ...

  6. SQLSERVER LATCH WINDBG

    https://mssqlwiki.com/2012/09/07/latch-timeout-and-sql-server-latch/

  7. lync项目总结

    概述 9月份,由于公司人事变动,摆在自己面前也有两条路可选择,一是选择lync,二是选择sharepoint,由于之前,部门老大已经让我看了大概一个月的有关lync方面的资料(文档,代码,项目实施等) ...

  8. mongodb_命令行

    一.打开命令行 cmd --> cd C:\Program Files\MongoDB\Server\3.0\bin\ --> mongo.exe   二.连接远程机器命令行工具 1.连接 ...

  9. JET 调用后端Rest Service

    调用Rest Service可以基于两种方式: 一种是oj.Collection.extend 一种是$.ajax CORS问题 但在调用之前,首先需要解决rest service的CORS问题.(跨 ...

  10. linux如何安装xampp,以及融合dvwa

    1.官网下载:https://www.apachefriends.org/download.html 2.赋予执行权限 [admin@19-56 ~]$ chmod +x xampp-linux-x6 ...