mibbp

检验赛d题题解

  链接:https://vjudge.net/contest/418598#problem/D

  这个题很容易会想到去分离位数,然后加起来是三的倍数那么这个数就是三的倍数,然后我一开始的想法是把位数分离,把不是三的倍数的位数存到一个数组,然后先删掉一个位数去看剩下的和是不是三的倍数,没有的话ans++,然后去删两个,直到全部删掉ans就是-1,但是这样我觉得会超时(其实是我搜索不太行),然后在我去拿一些数据分离位数然后去想的时候发现,其实不需要把所有的位数存到数组里,因为所有的位数其实都可以看成1,2.为什么呢,因为我们的位数要加起来去余3,就比如a+b+c%3,就是a%3+b%3+c%3,而%3的结果只有1,2,发现了这个·就很简单了,用a[1]去记是%3==1的位数出现的次数,a[2]去记%3==2的位数出现的次数.

  然后这么想,如果所有位数%3余数为1,这个1是怎么来的,有两种情况,一种是一个1,或者两个2,如果是两个1余数是2,3个1余数为0,四个1相当于一个1,同理2也是这样,所以总和余数出现了1,只需要删掉一个1,或者两个2,但是这个时候就有特例比如说1,1%3的余数是1按理删掉一个1就可以了,但是用脚想都知道1凑不出3的倍数,所以这种情况特判呗,就是只有一位数这位书为1类数输出-1,同理22也是,当是两位数且是2类数输出-1.

  那么余数是2的情况也是类似,有两种情况,一种就是一个2类数,一种就是两个1类,只需要删掉一个2类或者2个一类就可以了,只有一位2类数和两位1类数要特判。

  最后删掉一个ans++,删不掉ans=-1然后一开始直接判断是不是3的倍数。

  代码:

#include<stdio.h>
#include<stdlib.h>
long long a[3];
int main(){
    long long n,sum=0,ans=0,nn,cou=0;
    scanf("%lld",&n);
    nn=n;
    if(n%3==0){
        printf("0");
        exit(0);
    }
    while(n){
        a[n%10%3]++;
        sum+=n%10;
        n/=10;
        cou++;
    }
    if(sum%3==1){
        if(a[1]>0&&cou>1)ans=1;
        else if(a[2]>=2&&cou>2)ans=2;
        else ans=-1; 
    }
    else{
        if(a[2]>0&&cou>1)ans=1;
        else if(a[1]>=2&&cou>2)ans=2;
        else ans=-1;
    }
    printf("%lld",ans);
    return 0;
}

 

posted on 2021-01-21 21:42  mibbp  阅读(128)  评论(0编辑  收藏  举报

导航