C++,codeforces,2050C,C. Uninteresting Number

/*
codeforces,2050C,C. Uninteresting Number
题目描述
给一个整数n
可以对它的任意一位进行如下操作:
将该位数字平方后,若结果不超过一位,则该位替换为平方后的结果
问通过任意次操作后得到一个能否被9整除的数
*/
/*
判断一个数能否能被3整除,只需要判断其各位数字之和能否被3整除
以下等号均为mod 3下的等号
10 % 3 = 1
a*b % 3 = (a%3 * b%3) % 3 
==> 10^x % 3 = (1%3)^x % 3 = 1 
(a+b) % 3 = (a%3+b%3) % 3
==>a*10^x % 3 = a*(10^x%3) % 3= a % 3
==> 20 % 3 = 2 % 3; 500 % 3 = 5 % 3
==> 123 % 3 = (100%3+2=%3+3%3) % 3 = (1+2+3) % 3
因此若数字abcde % 3 == 0, 则a+b+c+d+e % 3 == 0

10%9 = 1 ...

判断一个数能否被9整除,只需要判断其各位数字之和能否被9整除

可以进行平方后替换的数字
0->0//各位数字之和不变,不会造成影响
1->1//各位数字之和不变,不会造成影响
2->4//导致各位数字和+2
3->9//导致各位数字和+6,相当于+2,+2,+2
所以通过平方后替换, 数字和只能增加2的倍数

将各位数字求和,结果若不为9的倍数,需要加上一定的值使其成为9的倍数
要看结果能否通过若干个+2和若干个+6使其成为9的倍数
即看(a+b)%9 = (a%9+b)%9 能否 == 0
可以看a对9的余数需要加上什么(b)才能%9 == 0

有0,1,2,3,4,5,6,7,8共9中可能
其中1,2,3,4,5,6,7,8需要加上对9的补数才能被9整除
它们分别需要加上对9的补数才能被9整除
1,   2,   3,   4,   5,   6,   7,   8     得到的一位数
8,   7,   6,   5,   4,   3,   2,   1     补数
4*2, 8*2, 3*2, 7*2, 2*2, 6*2, 1*2, 5*2   模9的情况下为了得到补数需要的2的个数
8,   16,  6,   14,  4,   12,  2,   10    相当于加上的数(2*n)
 
那么,能够通过平方后替换而将最终结果补齐为9的倍数的数字有
1+8=9,  2+7=9,  3+6=9,  4+5=9,  5+4=9,  6+3=9,  7+2=9,  8+1=9
1+8=9,  2+16=18,3+6=9,  4+14=18,5+4=9,  6+12=18,7+2=9,  8+10=18

得出了各位求和的结果的一位数与它们分别需要的2的个数x
1-4,2-8,3-3,4-7,5-2,6-6,7-1,8-5

在对原数字的每一位的处理时统计2和3的个数,
一个2说明有一个2可以使用, 统一1的个数
一个3说明有三个2可以一起使用,统计3的个数
判断这些2或6的各种组合能否满足需要的2的个数
最后判断需要的2的个数x是否可以有已有的若干个1和若干个3组合得到
*/
#include <string>
#include <iostream>
#include <map>
#include <algorithm>
#include <numeric>
std::map<int,int> RemainTwoCount={
    //1-4,2-8,3-3,4-7,5-2,6-6,7-1,8-5
    {1,4},{2,8},{3,3},{4,7},{5,2},{6,6},{7,1},{8,5}
    };
bool judge(std::string num){
    int countOf2=std::count(num.begin(),num.end(),'2');//1
    int countOf3=std::count(num.begin(),num.end(),'3');//3
    int sum = std::accumulate(num.begin(),num.end(),0)-'0'*num.size();
    int remain = sum%9;
    // int remain = std::stoi(num)%9;
    if(remain==0){
        return true;
    }else{
        //=========================================1
        // 77ms 0KB
        // int neededCount = RemainTwoCount[remain];
        // while(neededCount>=3 && countOf3>0){
        //     countOf3--;neededCount-=3;
        // }
        // while(neededCount>=1 && countOf2>0){
        //     if(neededCount>0 && countOf2>0){
        //         countOf2--;neededCount--;
        //     }
        // }
        // return neededCount == 0;

        //=========================================2
        // 62ms 0KB
        // int neededCount = RemainTwoCount[remain];
        // if(neededCount<=countOf2){
        //     return true;
        // }
        // int remainderOf3 = (neededCount-countOf2)%3;
        // int needed3 = (neededCount-countOf2)/3;

        // if(countOf3>=needed3 && remainderOf3==0){
        //     return true;
        // }else if(countOf3>=(needed3+1) && (3-remainderOf3)<=countOf2){
        //     return true;
        // }
        // return false;

    }
}
int main(){
    int count;
    std::cin>>count;
    for(auto i=0;i<count;i++){
        std::string num;
        std::cin>>num;
        if(judge(num)){
            std::cout<<"YES"<<std::endl;
        }else{
            std::cout<<"NO"<<std::endl;
        }
    }
}
posted @ 2025-02-11 11:52  Kazuma_124  阅读(69)  评论(0)    收藏  举报