dp处理大数整除6的最大位数Divide by Six

来源:互联网 发布:海口哪里有mac专柜 编辑:程序博客网 时间:2024/06/05 10:12

                                                    题址:https://oj.ejq.me/problem/24   

 Divide by Six

Input file: standard input
Output file: standard output
Time limit: 1 second
Memory 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
题意:一个小于等于100000位的数字n,(10^100000>=n>=1);在这个数字中选出一些数字(不可改变顺序)组成6的倍数,输出符合条件的最长的位数。

例如样例0010456,选1056符合条件。如果找不到符合条件的则输出-1s;

(下面出现的余数都表示取余6的余数)

思路:首先int dp[100010][6];dp【i】【j】表示前i位(余数为j)的最长的位数;

dp初始化为-1e9;用ans来存最大值,ans初始化也为-1e9。如果数字中有0的话,ans至少是1;

dp【i】【0】一定表示前i位能整除6的最大位数。

因为dp【i】【j】可以由dp【i-1】【k】+1得来。

下面的t表示第i位上的数字。

状态转移方程:dp[i][(j*10+t)%6]=max(dp[i][(j*10+t)%6],dp[i-1][j]+1);  

附上AC代码:

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<cmath>#include<string>#define LL long long int#define inf 0x3f3f3f3f#define N 1000010using namespace std;char a[100005];int dp[100005][7];int main(){    while(~scanf("%s",a+1))    {        int n=strlen(a+1);        for(int i=0;i<=n;i++)            for(int j=0;j<6;j++)                dp[i][j]=-inf;            int ans=-inf;            for(int i=1;i<=n;i++)                if(a[i]=='0')            {                   ans=1;                break;            }           for(int i=1;i<=n;i++)           {               int t=a[i]-'0';               if(t!=0)                dp[i][t%6]=max(dp[i][t%6],1);               for(int j=0;j<6;j++)               dp[i][j]=max(dp[i-1][j],dp[i][j]);               for(int j=0;j<6;j++)               {                   dp[i][(j*10+t)%6]=max(dp[i][(j*10+t)%6],dp[i-1][j]+1);               }               ans=max(ans,dp[i][0]);           }           if(ans>0)            printf("%d\n",ans);           else            printf("-1s\n");    }}
比赛后看第一名的代码,才知道原来这题能用dp做。这真是一道好题啊啊啊。
杭电的一道类似题:http://acm.hdu.edu.cn/showproblem.php?pid=6020  都是好题。









0 0
原创粉丝点击