重要数学知识:能被9整除,在于各位数之和为9的倍数,即summ % 9 = 0,
如果有余数,那么余数就是差的部分。
0 1 没必要; 2 3 能平方; 4-9 都不行;一个2贡献2的增量,一个3贡献6的增量
因此我们要统计整个字符串里2和3出现的次数cnt_2,cnt_3,
然后以2和3的次数为上限进行双重for循环,找到一个序列(i,j)补齐余数。
值得优化的是:2最大只需要遍历到第八个即可( (增量2*9=18) %9 = 0),第九个以后进入轮回,
3最大遍历到第2个( (增量6*3 = 18) %9 = 0 ),第三个以后进入轮回。
#include <iostream>
#include <string>
using namespace std;
int main() {
int t;
cin >> t;
while (t--) {
string n;
cin >> n;//1234567890
int cnt_2 = 0, cnt_3 = 0;
long long summ = 0;
for(char x: n){
if (x == '2') {
cnt_2++;//1
}
else if (x == '3') {
cnt_3++;//1
}
summ += x-'0';
}
int yu = summ % 9;//计算距离9已经走了多少
if (yu == 0) {//余数为0直接就是9的倍数了
cout << "YES" << '\n';
continue;
}
int need_to_add = (9 - yu) % 9; //计算距离9还差多少
int flag = 0;//为1说明经过调整后可以变成9的倍数
for (int i = 0; i <= min(cnt_2, 8); i++) {
for (int j = 0; j <= min(cnt_3, 2); j++) {
if ((i*2 + j*6) % 9 == need_to_add) {//记得加和取模9
flag = 1;// 找到了满足序列
break;
}
}
}
if (!flag) {
cout << "NO" << '\n';
}
else {
cout << "YES" << '\n';
}
}
}

京公网安备 11010502036488号