刚开始是用深搜做的,写了个暴力搜索,27个样例最后过了26个,最后一个T了,欲哭无泪。。。
去cf上看了一些题解,基本上都使用DP解决,不过今天在浏览博客的时候发现用数论的解法解决的(应该是数论?还没学)
原来还能这样做,确实强。
首先要了解的是(a + b + c ) % d = a % d + b % d + c % d。
然后判断一个数字是否是3的倍数的话,直接将各位数字加起来求和判断其是否是3的倍数就行了,或者它对3取模求得的余数就是原来数字的余数。
并且可知 3 6 9 模 3等价,2 5 8模3等价, 1 4 7模3等价,那么就统计一下每个数字模3之后的数字的总个数,用一个数组保存起来。
在进行判断的时候,假设数字为两位数,那么如果模3为1,就代表1这个数字位多出来了,那么只需要去掉一个1就行了,也就是只需要一步操作,对2同理(这时候只需要去掉一个2)。
假如数字大于两位,如果模3为1,那么也是1多出来了,需要去掉1,如果cnt[1] == 0,而cnt[2]>=2,那么需要去掉两个2,对于模2同理。
如果这两种操作都不行,那么直接输出-1.
代码如下:
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 typedef long long LL; 5 int cnt[3]; 6 int main(){ 7 LL a; 8 cin >> a; 9 if(a % 3 == 0){ 10 cout << 0 << endl; 11 return 0; 12 }else if(a <= 2){ 13 cout << -1 << endl; 14 return 0; 15 } 16 int tot = 0, sum = 0; 17 while(a){ 18 int temp = a % 10; 19 sum += temp; 20 tot ++; 21 cnt[temp % 3] ++; 22 a /= 10; 23 } 24 if(sum % 3 == 1){ 25 if(tot > 1 && cnt[1] >= 1) 26 cout << 1 << endl; 27 else if(tot > 2 && cnt[2] >= 2) 28 cout << 2 << endl; 29 else 30 cout << -1 << endl; 31 }else if(sum % 3 == 2){ 32 33 if(tot > 1 && cnt[2] >= 1) 34 cout << 1 << endl; 35 else if(tot > 2 && cnt[1] >= 2) 36 cout << 2 << endl; 37 else 38 cout << -1 << endl; 39 } 40 41 42 return 0; 43 }