题解 CF2050C

· · 题解

题意:

给定一个大数,每次可以对任意一个十进制位乘方然后放回原处,不允许增加位数,问随意操作后是否可以整除 9

思路:

题目不允许增加位数,只有 1,2,3 可以操作,而 1 不会产生任何贡献,直接考虑 2,3

当对 2 进行乘方操作时,2 会变成 4,对结果的贡献是 2。同理,3 进行操作的贡献是 6。要使最终大数整除 9,必须使其数位之和整除 9

不难发现实际的有效位数并不多,如果我们有足够的 2(多于 9 个),必然可以直接判可行,选定其中一些 2 乘方必然可以涵盖所有除以 9 的余数情况。而对于 3,它对结果余数的贡献是 6,3,0 的循环,实际最多需要考虑的有效位数只有 3 位。

只需要考虑小于 9233,直接暴力。

程序如下:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
int T,n;
char ch[100005];
int main(){
    scanf("%d",&T);
    while(T--){
        scanf("%s",ch+1);
        n=strlen(ch+1);
        int tot=0,cnt2=0,cnt3=0;
        for(int i=1;i<=n;i++){
            tot+=ch[i]-'0';
            if(ch[i]=='2')cnt2++;
            if(ch[i]=='3')cnt3++;
        }
        if(cnt2>=9||tot%9==0||(tot%3==0&&cnt3>=3)){
            printf("YES\n");
            continue;
        }
        bool flag=false;
        int newtot=tot;
        for(int j=1;j<=cnt3&&j<=3;j++){
            newtot+=6;
            if(newtot%9==0){
                flag=true;
                break;
            }
        }
        for(int i=1;i<=cnt2;i++){
            tot+=2;
            if(tot%9==0){
                flag=true;
                break;
            }
            int newtot=tot;
            for(int j=1;j<=cnt3&&j<=3;j++){
                newtot+=6;
                if(newtot%9==0){
                    flag=true;
                    break;
                }
            }
            if(flag)break;
        }
        if(flag)printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

THE END