首页 > 试题广场 >

九倍平方数

[编程题]九倍平方数
  • 热度指数:4368 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
\hspace{15pt}给定一个不含前导零的十进制数字串 n(长度 \leqq10^5)。你可以多次执行以下操作:
\hspace{23pt}\bullet\, 选择 n 中的某一位数字 x\ (0\leqq x\leqq9)
\hspace{23pt}\bullet\,x^2<10,将该位替换为 x^2

\hspace{15pt}若通过若干次(可为 0 次)操作可以使最终数字能被 9 整除,则称数字串 n 为好数。判断每个测试用例的数字串 n 是否为好数

输入描述:
\hspace{15pt}第一行输入整数 t\left(1\leqq t\leqq 10^4\right),表示测试用例数量。
\hspace{15pt}随后 t 行,每行一个数字串 n,长度 \leqq10^5,保证所有用例数字串 n 的总长度 \leqq10^5


输出描述:
\hspace{15pt}对每个用例输出 ``\text{YES}`` 或 ``\text{NO}``(大写),表示是否存在操作序列使得最终数字能被 9 整除。
示例1

输入

9
123
322
333333333333
9997
5472778912773
1234567890
23
33
52254522632

输出

NO
YES
YES
NO
NO
YES
NO
YES
YES

说明

在第一组样例中,从整数 123 中只能得到 123143129149 ,它们都不能被 9 整除。

在第二组样例中,需要将第二个数字替换为它的平方,那么 n 就等于 342 = 38 \cdot 9

在第三组样例中,整数已经可以被 9 整除。
一个数能整除9,则其各位数之和能整除9
发表于 2025-07-14 16:12:11 回复(0)
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;
                    }
                }
                if (isGood) break;
            }
            
            System.out.println(isGood ? "YES" : "NO");
        }
        scanner.close();
    }
}

发表于 2025-08-27 21:19:18 回复(0)
#include <stdio.h>
#include <string.h>
int main() {
    int t;
    scanf("%d",&t);
    while(t--){
        char n[100005];
        scanf("%s",n);
        long long sum=0;
        int len=strlen(n),num2=0,num3=0,flag=0;
        for(int i=0;i<len;i++){
            sum+=n[i]-'0';
            if(n[i]=='2'){
                num2++;
            }
            else if(n[i]=='3'){
                num3++;
            }
        }
        if(sum%9==0){
            printf("YES\n");
        }
        else{
            flag=0;
            for(int i=0;i<=num2;i++){
                for(int j=0;j<=num3;j++){
                    if((sum+i*2+j*6)%9==0){
                        printf("YES\n");
                        flag=1;
                        break;
                    }
                }
            }
            if(flag==0){
                printf("NO\n");
            }
        }
    }
    return 0;
}
这哪有问题呀 一个用例都没过😭😭救救孩子
发表于 2025-11-05 18:23:40 回复(2)
为什么我的代码无法通过最后一个测试例呀,显示段错误
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() {
    int t;
    scanf("%d",&t);

    while(t--){
        char *str = (char*)malloc(100001 * sizeof(char));
        scanf("%s",str);
        int length = strlen(str);
        int num2 = 0;
        int num3 = 0;
        int sum = 0;

        for(int i = 0; i < length; i++){
            int temp = str[i] - '0';
            sum += temp;
            if(temp == 2){
                num2++;
            }
            if(temp == 3){
                num3++;
            }
        }

        int flag = 0;

        for(int i = 0; i <= num2; i++){
            if(flag == 1)break;
            for(int j = 0; j <= num3; j++){
                int ans = sum + i * 2 + j * 6;
                if(ans % 9 == 0){
                    flag = 1;
                    printf("YES\n");
                    break;
                }
            }
        }

        if(flag == 0){
            printf("NO\n");
        }

        free(str);
    }
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() {
    int t;
    scanf("%d",&t);

    while(t--){
        char *str = (char*)malloc(100001 * sizeof(char));
        scanf("%s",str);
        int length = strlen(str);
        int num2 = 0;
        int num3 = 0;
        int sum = 0;

        for(int i = 0; i < length; i++){
            int temp = str[i] - '0';
            sum += temp;
            if(temp == 2){
                num2++;
            }
            if(temp == 3){
                num3++;
            }
        }

        int flag = 0;

        for(int i = 0; i <= num2; i++){
            if(flag == 1)break;
            for(int j = 0; j <= num3; j++){
                int ans = sum + i * 2 + j * 6;
                if(ans % 9 == 0){
                    flag = 1;
                    printf("YES\n");
                    break;
                }
            }
        }

        if(flag == 0){
            printf("NO\n");
        }

        free(str);
    }
}

发表于 2025-09-13 19:45:59 回复(1)
#include <iostream>
#include <string>
using namespace std;

// 1.关于这里为什么对2的个数限制在8个,3的个数限制在2个。
// 1.数的增量只能由2和3来,2的增量是4-2=2,3的增量是3*3-3=6.
// 2.我们要求的是 原来的数的和加上增量后可以被9整除 ( sum%9+(2*j+6*i) )%9==0
// 3.由于sum%9属于0-8范围内,因此 (2*j+6*i)%9 也应该在0-8范围内

// 余数 最小达到增量
// 1    10=2*5
// 2    2=2*1
// 3    12=2*6 or 12=6*2
// 4    4=2*2
// 5    14=2*7
// 6    6=2*3 or 6=6*1
// 7    16=2*8
// 8    8=2*4
// 由上表可以看出,2最大得有8个,6最大得有2个。

// 本题判断 9-sum%9==(2*j+6*i)%9即可

bool ist(string s) {
    int k = s.size();
    int sum = 0, n1 = 0, n2 = 0;
    for (int i = 0; i < k; i++) {
        sum += s[i] - '0';
        sum = sum % 9;
        if (s[i] == '2') n1++;
        if (s[i] == '3') n2++;
    }

    if (sum != 0) {
        int origin = 9 - sum;
        for (int i = 0; i <= min(n2, 2); i++) {
            for (int j = 0; j <= min(n1, 8); j++) {
                if (origin == (j * 2 + i * 6) % 9) {
                    return true;
                }

            }
        }
    } else {
        return true;
    }

    return false;

}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin >> n;
    while (n--) {
        string s;
        cin >> s;
        if (ist(s)) {
            cout << "YES" << endl;
        } else {
            cout << "NO" << endl;
        }

    }
}

发表于 2025-08-04 20:30:32 回复(0)
# 判断一个数是否能被9整除的条件是每一位数字的和能否被9整除.
# 能够变换平方的数字只有两个,2和3,分别变换为4和9,增量分别为2和6.
# 也就是给所有位数之和的增量分别为2和6.
# 找到所有2,3,把所有可能的增量计算一次,看能否整除9.
for _ in range(int(input())):
    flag = False
    c2 = 0
    c3 = 0 # count 2 and 3s
    num = list(map(int,input()))
    for s in num:
        if (s == 2):
            c2 += 1
        elif (s == 3):
            c3 += 1
    sums = sum(num)
    for i in range(c2+1):
        for j in range(c3+1):
            if ((sums + i * 2 + j * 6) % 9 == 0):
                flag = True
                break
        if flag:
            break
    if flag:
        print("YES")
    else:
        print("NO")

发表于 2025-12-01 01:12:17 回复(0)
#include <bits/stdc++.h>
#define int long long
using namespace std;
void solve() {
	string s;
	cin >> s;
	int n = s.size();
	vector<int> a(n);
	for (int i = 0; i < n; i++) {
		a[i] = s[i] - '0';
	}
	int sum  = accumulate(a.begin(), a.end(), 0ll);
	if (sum % 9 == 0) {
		cout << "YES\n";
		return ;
	}

	vector<vector<int>> f(n + 1, vector<int> (10));

	f[0][0] = 1;

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < 9; j++) {
			f[i + 1][(j + a[i]) % 9] |= f[i][j];
			if (a[i]*a[i] < 10) {
				f[i + 1][(j + a[i] * a[i] % 9) % 9] |= f[i][j];
			}
		}
	}

	cout << (f[n][0] ? "YES" : "NO") << "\n";
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	int T = 1;
	cin >> T;
	while (T--) {
		solve();
	}
	return 0;
}

发表于 2025-11-03 19:43:46 回复(1)
#include <stdio.h>
#include <string.h>
int main() {
    int n;
    char ch[100001];
    int m=0,k=0;
    long long sum=0;
    int n2=0,n3=0,flag=0,r=0,target_mod=0,max_a=0,max_b=0;
    scanf("%d",&n);
    getchar();
    for(int i=0;i<n;i++)
    {
        m=0;sum=0;n2=0;n3=0;flag=0;k=0;target_mod=0;max_a=0;max_b=0;r=0;
        fgets(ch, sizeof(ch), stdin);
        ch[strcspn(ch, "\n")] = '\0';
        while(ch[m]!='\0')
        {
            if(ch[m]=='2')
            {
                n2++;
            }
            if(ch[m]=='3')
            {
                n3++;
            }
            sum+=ch[m]-'0';
            m++;
        }
        r=sum%9;
        if(r==0)
        {
            printf("YES\n");
            continue;
        }
        target_mod = (9 - r) % 9;
        max_a = (n2 < 9) ? n2 : 8;
        max_b = (n3 < 3) ? n3 : 2;
        for(int a=0;a<=max_a;a++)
        {
            int break_outer = 0;
            for(int b=0;b<=max_b;b++)
            {
                if((2*a + 6*b) %9 == target_mod)
                {
                    flag=1;
                    break_outer = 1;
                    break;
                }
            }
            if(break_outer) break;
        }
        if(flag)
        {
            printf("YES\n");
        }
        else
            printf("NO\n");
    }

    return 0;
}
1. 利用模运算的周期性,减少枚举范围
关键观察:
操作对总和的增量是 2a + 6b(a 是数字 2 的使用次数,b 是数字 3 的使用次数),而我们只关心这个增量对 模 9 的结果(因为目标是让 (初始总和 + 增量) % 9 == 0)。
2a % 9 的可能结果:仅与 a % 9 有关(因为 2*(a+9) %9 = (2a + 18) %9 = 2a%9)。
6b % 9 的可能结果:仅与 b % 3 有关(因为 6*(b+3) %9 = (6b + 18) %9 = 6b%9)。
因此,a 只需枚举 0~min(n2, 8)(超过 9 的部分重复模 9 结果),b 只需枚举 0~min(n3, 2)(超过 3 的部分重复模 9 结果),循环次数从 n2*n3 降至 9*3=27 次,效率极大提升。
2. 提前计算目标模值,简化判断条件
设初始总和的模 9 余数为 r = sum % 9,我们需要增量 2a + 6b 满足:
(r + 2a + 6b) % 9 == 0
即 (2a + 6b) % 9 == (9 - r) % 9(记为 target_mod)。
循环中只需判断 (2a + 6b) %9 是否等于 target_mod,无需每次计算与 r 的和,逻辑更清晰。
3. 循环内提前 break,避免无效计算
当找到一组有效的 a 和 b 时(即满足模 9 条件),可以立即跳出所有循环,无需继续枚举其他可能,减少不必要的计算。
发表于 2025-10-21 16:55:23 回复(1)
暴力枚举+丑陋剪枝,终于不超时了
运行时间174ms
占用内存8308KB
import sys

n = int(input())
for _ in range(n):
    line = input()
    arr = list(map(int, line))
    total = sum(arr) % 9
    if total == 0:
        print("YES")
        continue
    # print(arr)
    mc = arr.count(2)
    nc = arr.count(3)
    if total == 1 and mc > 0 and nc > 0:
        print("YES")
        continue
    if total == 2:
        if (mc >= 2 and nc >= 2) or (mc >= 5 and nc >= 1) or mc >= 8:
            print("YES")
            continue
    if total == 3 and nc > 0:
        print("YES")
        continue
    if total == 4:
        if (
            (mc >= 16)
            # or (mc >= 13 and nc >= 1)
            # or (mc >= 10 and nc >= 2)
            # or (mc >= 7 and nc >= 3)
            # or (mc >= 4 and nc >= 4)
            or (mc >= 1 and nc >= 5)
        ):
            print("YES")
            continue
    if total == 5 and mc >= 2:
        print("YES")
        continue
    if total == 6:
        if (
            (nc >= 2)
            or (mc >= 6)
        ):
            print("YES")
            continue
    if total == 7 and mc >= 1:
        print("YES")
        continue
    if total == 8:
        if mc >=5:
            print("YES")
            continue
    ans = False
    for i in range(mc + 1):
        for j in range(nc + 1):
            if (total + i * 2 + j * 6) % 9 == 0:
                ans = True
                break
                break
    if ans:
        print("YES")
    else:
        print("NO")


发表于 2025-09-26 00:08:14 回复(0)
t = int(input())
for i in range(t):
    n = input()
    num_2 = 0
    num_3 = 0
    sum_others = 0 # 不为2、3数的和
    for j in n:
        j = int(j)
        if j==2:
            num_2 += 1
        elif j==3:
            num_3 += 1
        else:
            sum_others += j
    sum_all = sum_others+2*num_2+3*num_3
    if sum_all%9==0:
        print('YES')
    else:
        flag = False
        for x in range(num_2+1):
            for y in range(num_3+1):
                if (sum_all+2*x+6*y)%9==0:
                    print('YES')
                    flag = True
                    break
            if flag:
                break
        if not flag:
            print('NO')
发表于 2025-08-24 18:30:23 回复(0)
t = int(input())
def solve():
    s =list(map(int, input()))
    total = sum(s)
    f = total
    # print(total)
    if total%9==0:
        print("YES")
        return
    h = {
        2:0,
        3:0
    }
    for i in s:
        if i==2:
            h[2]=h[2]+1
        elif i==3:
            h[3]=h[3]+1
    # print(h)
    for i in range(h[2]+1):
        for j in range(h[3]+1):
            total = total + i*2 + j*6
            # print(total)
            if total%9==0:
                print("YES")
                return
            else:
                total = f
    print("NO")    
for _ in range(t):
    solve()

# 呃呃

发表于 2025-06-25 03:38:29 回复(0)