WOJ 24. Divide by Six

題目

請以此題面爲準
無解時輸出-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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章