要解决这个问题,我们需要判断一个数字串是否能通过特定操作(将数字替换为其平方,仅当平方小于 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(); } }