/**
题目:C. Divide by Six
链接:https://oj.ejq.me/problem/24
题意:给定一个数,这个数位数达到1e5,可能存在前导0.问为了使这个数是6的倍数,且没有前导0,删除尽量少的位数,可以任意位置删除。
输出剩余的位数。如果找不到,输出-1s。
思路:
一开始心想,这么多个位置,又不知道删除几个,排列组合的情况下,简直不可能完成。
这题是我的队友tzq想出来的。在此重新思考一下。
常规想法不可能完成。一定存在某些特殊的地方。观察题目要求,6的倍数。一个数是6的倍数有什么特殊性?
尾数一定是偶数。那么枚举尾数为偶数,仍然很大。
假设确定了一定是2的倍数,那么只要判断是否是3的倍数就行了。而判断一个数是否是3的倍数,只要各个数位的和是3的倍数这个数就一定是3的倍数。很容易证明。 如果找到一个尾数为偶数,且从它为尾的数%3==0.那么这个可能是答案。
%3==1.那么要删除一个某个位的数%3==1的位。或者删除两个数位上的数%3==2的位。为了避免删除后出现前导0,为了答案最优,从右边开始找。如果找不到,所以这种情况无解。
如果删除后出现前导0,去掉前导0,不会有影响。注意把数删完了的情况。此时无解。
%3==2.那么删除一个某个位的数%3==2的位,或者删除两个数位上的数%3==1的位,同上。 问题是:尾数为偶数有很多种情况。我们知道为了让剩余的位数越来越多。所以选择尾数为偶数应该尽量右才好。
如果某两个位作为尾数。以他们为尾数的数%3==0,则显然取尾数更右的更优。
同理%3==1, %3==2,都是选更右的更优,这样删除的选择更多,且剩余的数位也更多。 至此,本体解法为分析+模拟。
细节:只要有前导0,肯定有答案。即剩余的数位0.那么输出1;
*/
#include<bits/stdc++.h>
#define LL long long
using namespace std;
typedef long long ll;
const int maxn = 1e5+;
char s[maxn];
int r[maxn];
int rr[maxn];
char temp[maxn];
int r0, r1, r2;///%3==0, %3==1, %3==2的尾数位置。
int leadzero, len, ans;
int getR(int type)
{
for(int i = len-; i>= ; i--){
if(r[i]==type&&(s[i]-'')%==){
return i;
}
}
return -;
}
void f(int r,int type)
{
if(r==-) return ;
///type==1
if(type==)
{
/// 删除一个1
for(int i = r; i >= &&r>; i--){
if(rr[i]==){
if(i==){
int t = i+;
while(t<=r&&temp[t]==''){
t++;
}
if(t>r){
ans = max(ans,);
}else
{
ans = max(ans,r-t+);
}
}else
{
ans = max(ans,r);
}
}
}
/// 删除两个2
int cnt = , pos = -;
char tt;
for(int i = r; i >= &&r>; i--){
if(rr[i]==){
cnt--;
if(cnt==){
if(i==){
int t = i+;
while(t<=r&&temp[t]==''){
t++;
}
if(t>r){
ans = max(ans,);
}else
{
ans = max(ans,r-t+);
}
}else
{
ans = max(ans,r);
}
}else
{
pos = i;
tt = temp[i];
temp[i]='';
}
}
}
if(pos!=-) temp[pos] = tt; }else
///type==2
{
///删除一个2
for(int i = r; i >= &&r>; i--){
if(rr[i]==){
if(i==){
int t = i+;
while(t<=r&&temp[t]==''){
t++;
}
if(t>r){
ans = max(ans,);
}else
{
ans = max(ans,r-t+);
}
}else
{
ans = max(ans,r);
}
}
}
///删除两个1
int cnt = , pos = -;
char tt;
for(int i = r; i >= &&r>; i--){
if(rr[i]==){
cnt--;
if(cnt==){
if(i==){
int t = i+;
while(t<=r&&temp[t]==''){
t++;
}
if(t>r){
ans = max(ans,);
}else
{
ans = max(ans,r-t+);
}
}else
{
ans = max(ans,r);
}
}else
{
pos = i;
tt = temp[i];
temp[i]='';
}
}
}
if(pos!=-) temp[pos] = tt;
}
}
int main()
{
while(scanf("%s",s)==)
{
r0 = r1 = r2 = -;
leadzero = ;
while(s[leadzero]!='\0'&&s[leadzero]==''){
leadzero++;
}
if(s[leadzero]=='\0'){
printf("1\n"); continue;
}
if(leadzero>) ans = ;///只要有前导0,那么肯定可以一个0作为结果。
strcpy(temp,s+leadzero);
// printf("temp = %s\n", temp);
strcpy(s,temp);
len = strlen(s);
int p = ;
for(int i = ; s[i]!='\0'; i++){
p = p+(s[i]-'');
p %= ;
r[i] = p;
rr[i] = (s[i]-'')%;
}
ans = -;
r0 = getR();
if(r0!=-) ans = r0+;
r1 = getR();
r2 = getR();
f(r1,);
//strcpy(temp,s);
f(r2,);
if(ans!=-){
printf("%d\n",ans);
}else printf("-1s\n");
}
return ;
}

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. Oracle数据库冷备份与恢复(救命稻草)

    说明,只要是同样系统,同样数据库版本,是可以做冷备恢复.冷备份数据必须是数据库不在open状态下.以oracle11gR2为例. 一.冷备份与冷恢复 具体步骤如下. 1. 复制旧的数据库文件 (1) ...

  2. JVM Object Query Language (OQL) 查询语言

    Object Query Language (OQL) OQL is SQL-like query language to query Java heap. OQL allows to filter/ ...

  3. C/C++ Windows移植到Linux

    近期写了有关Socket的程序,需要从windows移植到linux.现把有用的东东收集整理记录下来. 1.头文件windows下winsock.h或winsock2.h:linux下netinet/ ...

  4. iOS:Objective-c的MD5/SHA1加密算法的实现

    介绍: Objective-c实现MD5和SHA1算法相对还是比较简单的,可以直接调用系统的C/C++共享库来实现调用MD5即Message Digest Algorithm 5(信息-摘要算法 5) ...

  5. grpc(3):使用 golang 开发 grpc 服务端和client

    1,关于grpc-go golang 能够能够做grpc的服务端和client. 官网的文档: http://www.grpc.io/docs/quickstart/go.html https://g ...

  6. 转:facebook 开源工具集合

    http://codekk.com/blogs/detail/Trinea/Facebook%20%E7%9A%84%E9%82%A3%E4%BA%9B%E5%BC%80%E6%BA%90%E9%A1 ...

  7. rails delegate机制

    Delegate是一种应用composite来代替extend的机制,可以有效地降低代码的耦合性. Rails 2.2增加了delegate方法,可以十分方便地实现delegate机制. 01.def ...

  8. 金典 SQL笔记(2)

    由于在本地笔记上写的.CSDN markdown编辑器仅仅支持.md格式导入, 图片没办法直接导进去.写的多了懒的一张一张图片切图上传; 直接整个文章切成图片上传上去了.

  9. VBA【遍历每个工作表并将工作表表名赋予B2单元格】

    方法一:  存在缺陷:选中所有单元格,批量生成公式时候,每次需要点击进入工作表点击单元格--进入编辑状态,然后公式才会生效 使用公式如下: =,) 附件下载地址:点击下载 方法二: 使用宏编程进行复制 ...

  10. javascript 和 jquery 博客

    http://www.cnblogs.com/starof/category/626164.html