woj-Divide by Six

来源:互联网 发布:linux服务器绑定域名 编辑:程序博客网 时间:2024/06/17 21:39

无解时输出-1s而不是WTF

数据可能有前导零

Input file: standard inputOutput file: standard output Time limit: 1 secondMemory limit: 512 mebibytes

A positive integer number n is written on a blackboard. It consists of not more than 10^5105 digits. You have to transform it into a mogicalnumber by erasing some of the digits, and you want to erase as few digits as possible.

The number is lucky if it consists of at least one digit, doesn't have leading zeroes and is a multiple of 6. For example, 0, 66,66666 are lucky numbers, and 00, 25, 77 are not.

Write a program which for the given nn will find a mogical number such that nn can be transformed into this number by erasing as few digits as possible. You can erase an arbitraty set of digits. For example, they don't have to go one after another in the number nn.

Print the length of your answer after the erasing.

If it's impossible to obtain a lucky number, print -1s.

Input

The first line of input contains nn -- a positive integer ( 1\le n \le 10^{100000}1n10100000 ).

Output

Print one number — the number of your lucky number obtained by erasing as few as possible digits. If there is no answer, print -1s.

Example

Input 1

0010456

Output 1

4

Input 2

11

Output 2

-1s

题目大意:

删去几个数让它成为幸运数,幸运数是指没有前导0,能整除6

题目思路:首先我们分析可以知道,对于每个位的数字有删和删两种选择,那么我们可以想到dp,就可以往dp上去想,首先我们尝试去定义问题,我么可以想到,把前i位数当成一个阶段,0~5当成次阶段的状态,而当前阶段的状态又依赖前面的状态,那我们可以定义状态dp[i][j]代表前i位数mod6这个状态所需要删去的最小个数,剩下的只有状态转移了,我们可以发现前i位数j的值可以有前一个阶段直接得来,也就是删掉第i位,也可以有当前位数重新%6的来,dp[len][0]就是答案,注意下对前导0的处理,以及边界的更新处理

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
char s[1000000+5];
int dp[1000000+5][7];
int ans;
int main()
{
    while(~scanf("%s",s+1))
    {
        int len=strlen(s+1);
        //cout<<len<<endl;
        ans=0x3f3f3f3f;
        memset(dp,0x3f3f3f3f,sizeof(dp));
        //如果有0,那么最大值为len-1;
        for(int i=1;i<=len;i++)
            if(s[i]=='0')
                ans=len-1;
        for(int i=1;i<=len;i++)
        {
            int t=s[i]-'0';
            //相当于边界的初始化&&防止前道0
            if(t!=0)
            {
                dp[i][t%6]=i-1;
            }
            //每个阶段的每种状态
            for(int j=0;j<6;j++)
            {
                //删掉当前的点
                dp[i][j]=min(dp[i-1][j]+1,dp[i][j]);
                //不删
                dp[i][(j*10%6+t%6)%6]=min(dp[i][(j*10%6+t%6)%6],dp[i-1][j]);


            }
        }
        ans=min(ans,dp[len][0]);
        if(ans==0x3f3f3f3f)
            puts("-1s");
        else
            cout<<len-ans<<endl;
    }
    return 0;
}

0 0
原创粉丝点击