您的位置:首页 > 其它

WOJ 24. Divide by Six

2017-04-10 20:08 337 查看

题目

请以此题面为准

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

数据可能有前导零

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

10510^5

10

​5

​​ 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

n will find a mogical number such that

nn

n 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

n.

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

n – a positive integer (

1≤n≤10100000 1\le n \le 10^{100000}

1≤n≤10

​100000

​​ ).

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

题目分析

一道非常好的dp题,不是很难,但是细节问题很多,比赛的时候瞎搞的,搞了半天没出来,亏我还是队里面写dp的,非常惭愧,比赛的时候一直想着能被6整除的数是一个偶数并且各个数位上的数字相加和mod3等于0,然后写了2个小时,wa了11次,好气呀!!代码上有注释,参考大神解法。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1e5+100;
const int INF = 0x3f3f3f3f;

char s[maxn];
int dp[maxn][10];

int main(){
while(scanf("%s", s+1) != EOF){
int len = strlen(s+1);

for(int i = 0; i <= len; i++)
for(int j = 0; j < 6; j++) dp[i][j] = -INF;

int ans = -INF;
for(int i = 1; i <= len; i++)
if(s[i] == '0') ans = 1;
for(int i = 1; i <= len; i++){
int t = s[i] - '0';

/*这个位置是为了防止前导0,因为如果这个数不被初始化,那么这个数就是负无穷,
但是后一个状态可以根据前一个状态完成加1操作,但是这个负无穷加1任然为负无穷,
所以对最后的结果没有影响*/
if(t != 0) dp[i][t%6] = 1;

//要么当前值不选直接根据前一个值的情况
for(int j = 0; j < 6; j++)
dp[i][j] = max(dp[i][j], dp[i-1][j]);
for(int j = 0; j < 6; j++)  //当前值选取然后根据前一个点算出的6个值
dp[i][(j*10+t)%6] = max(dp[i][(j*10+t)%6], dp[i-1][j]+1);  //
ans = max(ans, dp[i][0]);  //注意mod6等于0
}

if(ans > 0) printf("%d\n", ans);
else printf("-1s\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: