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 3 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
- 1≤N<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 k−1digits, 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