题目相关
题目链接
AtCoder Beginner Contest 182 C 题,https://atcoder.jp/contests/abc182/tasks/abc182_c。
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.
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.
Samples1
Sample Input 1
35
Sample Output 1
1
Explaination
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.
Samples2
Sample Input 2
369
Sample Output 2
0
Explaination
Note that we can choose to erase no digit.
Samples3
Sample Input 3
6227384
Sample Output 3
1
Explaination
For example, by erasing the 8, we get the number 622734, which is a multiple of 3.
Samples4
Sample Input 4
11
Sample Output 4
-1
Explaination
Note that we must erase at least 0 and at most k−1 digits, 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.
Constraints
- 1≤N<10^18
- None of the digits in N is 0.
题解报告
题目翻译
给定一个正整数 N,数据中没有数字 0。问如果 N 不能被 3 整除,我们可以从 0 到 k-1 位中,任意删除,找出最小的删除位数。
样例数据分析
这个题目含义比较明确,我们不需要分析样例数据。
题目分析
我们知道,判断一个数字能否被 3 整除,我们只需要将该数字的所有构成数字求和,如何这个和可以被 3 整除,那么这个数肯定可以被 3 整除。N 的最大值是 1e18,因此 long long 是可以表示的。本题可以使用 getchar() 逐一读入每个位。
由于是判断能否被 3 整除,因此 0、3、6、9 是等效的;1、4、7 是等效的;2、5、8 是等效的。也就是每位数字 p 和 p%3 是等效的。这样我们可以设计出如下的算法:
1、逐位读入数据。逐一要忽略回车,也就是 '\n' 字符。将读取的数字记为 p;
2、将所有的 p 求和,记为 sum;
3、记录每位 p%3 的个数;
4、记录数据的位数,记为 tot;
5、分类讨论结果。
- sum 可以被 3 整数,说明数据 n 可以被 3 整数;
- sum%3 得到 1。说明 n 多了一个 1 相关位(对应的真实数据可以是 1、4、7)。我们只需要删除的方案有两种:1、当数据位数超过 1 的时候,删除一个 1;2、当数据位数超过 2 的时候,删除两个 2;3、上面两个可能都没有,就无法达成预期。
- sum%3 得到 2。说明 n 多了一个 2 相关位(对应的真实数据可以是 2、5、8)。我们只需要删除的方案有两种:1、当数据位数超过 1 的时候,删除一个 2;2、当数据位数超过 2 的时候,删除两个 1;3、上面两个可能都没有,就无法达成预期。
AC 参考代码
//https://atcoder.jp/contests/abc182/tasks/abc182_c
//C - To 3
#include <bits/stdc++.h>
using namespace std;
int main() {
long long n;
cin>>n;
//特判
if (0==n%3) {
cout<<"0\n";
return 0;
} else if (n<=2) {
cout<<"-1\n";
return 0;
}
//转换为数字
int cnt[3]={};//每个数字个数
int sum=0;//每个位数总和
int tot=0;//位数
while (n) {
int p=n%10;//取个位
n/=10;
sum+=p;
tot++;
cnt[p%3]++;
}
if (1==sum%3) {
if (tot>1 && cnt[1]>=1) {
cout<<"1\n";
} else if (tot>2 && cnt[2]>=2) {
cout<<"2\n";
} else {
cout<<"-1\n";
}
} else if (2==sum%3) {
if (tot>1 && cnt[2]>=1) {
cout<<"1\n";
} else if (tot>2 && cnt[1]>=2) {
cout<<"2\n";
} else {
cout<<"-1\n";
}
}
return 0;
}

时间复杂度
O(N)。

本文针对AtCoder初学者竞赛182-C题提供了解决方案。通过对输入数字N的每位进行分析,判断是否能通过删除部分位数使其成为3的倍数,并给出最少删除位数。采用模3的方法优化计算过程。
1095

被折叠的 条评论
为什么被折叠?



