要解决这个问题,我们需要判断一个数字串是否能通过特定操作(将数字替换为其平方,仅当平方小于 10 时)转化为能被 9 整除的数。核心依据是能被 9 整除的数的特性:各位数字之和能被 9 整除,结合操作对数字和的影响推导判断逻辑。
一、问题分析与核心逻辑
1. 操作对数字和的影响
仅当数字 x ∈ {0,1,2,3} 时可操作(因 x² < 10),操作后对数字和的贡献变化如下:
x=0/x=1:替换后仍为 0/1,数字和不变;x=2:替换为 4,数字和增加 2(仅可操作 1 次,后续 4 不可再操作);x=3:替换为 9,数字和增加 6(仅可操作 1 次,后续 9 不可再操作)。
2. 关键结论
S_base:数字串初始各位和(不操作时的和);cnt2:数字串中2的个数(每个可贡献 + 2 或 0);cnt3:数字串中3的个数(每个可贡献 + 6 或 0)。
我们需要判断是否存在 a ∈ [0,cnt2](选a个2操作)和 b ∈ [0,cnt3](选b个3操作),使得 (S_base + 2a + 6b) % 9 == 0。
3. 简化判断逻辑
由于 6b mod 9 仅存在 3 种可能值(6 * 3 = 18; 18 % 9 = 0 周期为 3);
由于 2a mod 9 仅存在 9 种可能值(2 * 9 = 18; 18 % 9 = 0 周期为 9);
因为我们只需要依次枚举 a, b 的值即可!
二、代码实现
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int t = scanner.nextInt();
scanner.nextLine(); // 吸收换行符
while (t-- > 0) {
String n = scanner.nextLine();
long sBase = 0; // 初始数字和
int cnt2 = 0; // 数字2的个数
int cnt3 = 0; // 数字3的个数
// 计算初始和及2、3的数量
for (char c : n.toCharArray()) {
int d = c - '0';
sBase += d;
if (d == 2) {
cnt2++;
} else if (d == 3) {
cnt3++;
}
}
boolean isGood = false;
// 枚举b的可能值(0, 1, 2),但不能超过实际数量cnt3
int maxB = Math.min(2, cnt3);
for (int b = 0; b <= maxB; b++) {
// 枚举a的可能值(0-8),但不能超过实际数量cnt2
int maxA = Math.min(8, cnt2);
for (int a = 0; a <= maxA; a++) {
// 计算当前总和:初始和 + 2a(每个2操作增加2) + 6b(每个3操作增加6)
long total = sBase + 2L * a + 6L * b;
if (total % 9 == 0) {
isGood = true;
break;
}
}
}
System.out.println(isGood ? "YES" : "NO");
}
scanner.close();
}
}

京公网安备 11010502036488号