AtCoder Beginner Contest 182C

C - To 3

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 300300 points

Problem Statement

Given is a positive integer N, where none of the digits is 0.
Let k be the number of digits in N. We want to make a multiple of by erasing at least 0 and at most k−1 digits from N and concatenating the remaining digits without changing the order.
Determine whether it is possible to make a multiple of 3 in this way. If it is possible, find the minimum number of digits that must be erased to make such a number.

Constraints

  • 1N<10^18
  • None of the digits in N is 0.

Input

Input is given from Standard Input in the following format:

N

Output

If it is impossible to make a multiple of 3, print -1; otherwise, print the minimum number of digits that must be erased to make such a number.


Sample Input 1 

35

Sample Output 1 

1

By erasing the 5, we get the number 3, which is a multiple of 3. Here we erased the minimum possible number of digits  1.


Sample Input 2 

369

Sample Output 2

0

Note that we can choose to erase no digit.


Sample Input 3

6227384

Sample Output 3 

1

For example, by erasing the 8, we get the number 622734, which is a multiple of 3.


Sample Input 4 

11

Sample Output 4

-1

Note that we must erase at least 0and at most k1digits, where k is the number of digits in N, so we cannot erase all the digits.
In this case, it is impossible to make a multiple of 3 in the way described in the problem statement, so we should print -1.

解题思路:题意是对N进行几次删除位数的操作能让删除后的位数为3的倍数,地球人都知道三的倍数有个特点,就是每一位相加之和是三的倍数

再看看数据的大小n是1e18的,很小可以直接搜索(但似乎听说正解是动规?喵喵喵?)

Code:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<string>

int cnt=0;
bool vis[30];

bool check(std::string ch) {//判断的函数,如果该数的各个位数之和为3的倍数则返回true
    int sum = 0;
    int len = ch.length();
    for(int i = 0; i < ch.length(); ++i) {
        sum += ch[i] - '0';
    }
    if(sum % 3)
    return false;
    cnt = std::max(len,cnt);//保证删除的位数最小
    return true;
}

void dfs(std::string ch,int loc) {
    if(check(ch)) {//如果找到了就不搜索了
        return;
    }
    for(int i = 0; i < ch.length(); ++i) {
        if(!vis[i]) {
            std::string temp = ch;
            temp.erase(i,1);//删除第i个位置的元素
            vis[i] = true;
            dfs(temp,i+1);
            vis[i] = false;//回溯搜索法
        }
    }
}

int main()
{
    int a,b;
    std::string ch;
    std::cin>>ch;
    dfs(ch,0);
    if(cnt == 0)//如果全都删了
    std::cout << -1 << "
";
    else
    std::cout << ch.length() - cnt << "
";
    return 0;
}

 简单的搜索hhh

原文地址:https://www.cnblogs.com/Mangata/p/13950678.html