MG loves apple BestCoder Round #93 1002

.http://acm.hdu.edu.cn/showproblem.php?pid=6020

BC题目质量高啊,可惜一个差不多得一个月才一场,,
思路:
首先可以想到将所有数字分对3取模,统计出余数为0,1,2的总数sum[3],接着进行穷举,对于选取了i个%3==2的数字和j个%3==1的数字,进行判断,是否合法,这里通过观察和总结,得出合法的条件如下:
假设sum0是指出现第一个x%3==0&&x!=0之前有多少个0的数量。
E1是指第一个0(或者没有出现)前有没有%3==1的数字出现。
E2是指第一个0(或者没有出现)前有没有%3==2的数字出现。
对于i,j,剩下选取0的个数为z=k-i-j,应满足:

(k-i-j>=sum0||(i<sum[2]&&E2)||(j<sum[1]&&E1))

穷举的所有情况只要有满足的则可以得到合法的数字,输出yes,否则输出no。

#include<bits/stdc++.h>
using namespace std;
int n,k,sum0,E1,E2,sum[3],sum_all;
char s[100005];
bool judge()
{
    int mod=sum_all%3;
    for(int i=0;i<=sum[2];i++)
    {
        for(int j=0;j<=sum[1];j++)
        {
            if(i+j>k) break;
            if(k-i-j>sum[0]) continue;
            if((i*2+j)%3!=mod)
                continue;
            if(k-i-j>=sum0||(i<sum[2]&&E2)||(j<sum[1]&&E1))
                return true;
        }
    }
    return false;
}
void cnt()
{
    int flag1=1;
    int flag2=1;
    for(int i=0;s[i]!='\0';i++)
    {
        sum[(s[i]-'0')%3]++;
        sum_all+=(s[i]-'0');
        if(!(s[i]-'0')&&flag1)
           {
            sum0++;
            flag2=0;
            }
        if((s[i]-'0')%3==1&&flag2)
            E1=1;
        if(((s[i]-'0')%3)==2&&flag2)
            E2=1;
        if((s[i]-'0')&&!((s[i]-'0')%3))
            flag1=0;
    }
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        cin>>n>>k;
        sum0=0,E1=0,E2=0,sum_all=0;
        memset(sum,0,sizeof(sum));
        scanf("%s",s);
        cnt();
        if(n-k<2)
         printf(sum[0]?"yes":"no");
        else
        {
          if(!k)
            printf(sum_all%3?"no":"yes");
          else
            printf(judge()?"yes":"no");
        }
        putchar(10);

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值